]> granicus.if.org Git - graphviz/commitdiff
mapgen plugin
authorellson <devnull@localhost>
Sun, 25 Jun 2006 03:50:58 +0000 (03:50 +0000)
committerellson <devnull@localhost>
Sun, 25 Jun 2006 03:50:58 +0000 (03:50 +0000)
lib/common/emit.c
lib/common/mapgen.c
lib/gvc/gvcjob.h
lib/gvc/gvrender.c
plugin/core/gvloadimage_core.c
plugin/core/gvrender_core_map.c
plugin/core/gvrender_core_ps.c
plugin/gd/gvrender_gd_vrml.c

index b91f27388e9a52df14d2a30347b5b11c119cc227..95cc4909a9f3ff9d9ea433385d2481b75e81ab1a 100644 (file)
@@ -619,8 +619,8 @@ static bool node_in_box(node_t *n, boxf b)
 static void emit_node(GVJ_t * job, node_t * n)
 {
     GVC_t *gvc = job->gvc;
-    char *s, *url = NULL, *tooltip = NULL, *target = NULL;
-    int oldstate, explicit_tooltip = 0;
+    char *s;
+    int oldstate;
 
     if (ND_shape(n) == NULL)
        return;
@@ -638,33 +638,11 @@ static void emit_node(GVJ_t * job, node_t * n)
            gvrender_comment(job, s);
         
        gvrender_begin_node(job, n);
-       if (((s = agget(n, "href")) && s[0]) || ((s = agget(n, "URL")) && s[0]))
-           url = strdup_and_subst_node(s, n);
-
-       if ((s = agget(n, "tooltip")) && s[0]) {
-           tooltip = strdup_and_subst_node(s, n);
-           explicit_tooltip++;
-       } else {
-           tooltip = strdup_and_subst_node(ND_label(n)->text, n);
-       }
-
-       if ((s = agget(n, "target")) && s[0])
-           target = strdup_and_subst_node(s, n);
-
-       if (url || explicit_tooltip)
-           gvrender_begin_anchor(job, url, tooltip, target);
-
        setColorScheme (agget (n, "colorscheme"));
        gvrender_begin_context(job);
        ND_shape(n)->fns->codefn(job, n);
        ND_state(n) = gvc->common.viewNum;
        gvrender_end_context(job);
-
-       if (url || explicit_tooltip)
-           gvrender_end_anchor(job);
-       free(url);
-       free(tooltip);
-       free(target);
        gvrender_end_node(job);
     }
     gvc->emit_state = oldstate;
@@ -1014,9 +992,8 @@ static bool edge_in_box(edge_t *e, boxf b)
 
 static void emit_edge(GVJ_t * job, edge_t * e)
 {
-    char *s, *url = NULL, *label = NULL, *tooltip = NULL, *target = NULL;
-    textlabel_t *lab = NULL;
-    int oldstate, explicit_tooltip=0;
+    char *s;
+    int oldstate;
 
     if (! edge_in_box(e, job->pageBoxClip) || ! edge_in_layer(job, e->head->graph, e))
        return;
@@ -1038,26 +1015,7 @@ static void emit_edge(GVJ_t * job, edge_t * e)
         gvrender_comment(job, s);
 
     gvrender_begin_edge(job, e);
-    if (((s = agget(e, "href")) && s[0]) || ((s = agget(e, "URL")) && s[0]))
-       url = strdup_and_subst_edge(s, e);
-    if ((lab = ED_label(e)))
-       label = lab->text;
-    if ((s = agget(e, "tooltip")) && s[0]) {
-       tooltip = strdup_and_subst_edge(s, e);
-       explicit_tooltip++;
-    } else if (label) {
-       tooltip = strdup_and_subst_edge(label, e);
-    }
-    if ((s = agget(e, "target")) && s[0])
-       target = strdup_and_subst_edge(s, e);
-    if (url || explicit_tooltip)
-       gvrender_begin_anchor(job, url, tooltip, target);
     emit_edge_graphics (job, e);
-    if (url || explicit_tooltip)
-       gvrender_end_anchor(job);
-    free(url);
-    free(tooltip);
-    free(target);
     gvrender_end_edge(job);
     job->gvc->emit_state = oldstate;
 }
@@ -1295,22 +1253,8 @@ void emit_view(GVJ_t * job, graph_t * g, int flags)
     GVC_t * gvc = job->gvc;
     node_t *n;
     edge_t *e;
-    char *s, *url = NULL, *tooltip = NULL, *target = NULL;
-    int explicit_tooltip = 0;
 
     gvc->common.viewNum++;
-    if (((s = agget(g, "href")) && s[0]) || ((s = agget(g, "URL")) && s[0]))
-       url = strdup_and_subst_graph(s, g);
-    if ((s = agget(g, "target")) && s[0])
-       target = strdup_and_subst_graph(s, g);
-    if ((s = agget(g, "tooltip")) && s[0]) {
-       tooltip = strdup_and_subst_graph(s, g);
-       explicit_tooltip++;
-    } else if (GD_label(g)) {
-       tooltip = strdup_and_subst_graph(GD_label(g)->text, g);
-    }
-    if (url || explicit_tooltip)
-        gvrender_begin_anchor(job, url, tooltip, target);
     if (GD_label(g))
        emit_label(job, EMIT_GLABEL, GD_label(g), (void *) g);
     /* when drawing, lay clusters down before nodes and edges */
@@ -1367,11 +1311,6 @@ void emit_view(GVJ_t * job, graph_t * g, int flags)
     /* when mapping, detect events on clusters after nodes and edges */
     if (flags & EMIT_CLUSTERS_LAST)
        emit_clusters(job, g, flags);
-    if (url || explicit_tooltip)
-       gvrender_end_anchor(job);
-    free(url);
-    free(tooltip);
-    free(target);
     gvrender_end_page(job);
 }
 
@@ -1508,8 +1447,7 @@ void emit_clusters(GVJ_t * job, Agraph_t * g, int flags)
     char *color, *fillcolor, *pencolor, **style;
     node_t *n;
     edge_t *e;
-    char *s, *url, *tooltip, *target;
-    int oldstate, explicit_tooltip;
+    int oldstate;
 
     oldstate = job->gvc->emit_state;
     job->gvc->emit_state = EMIT_CDRAW;
@@ -1521,24 +1459,6 @@ void emit_clusters(GVJ_t * job, Agraph_t * g, int flags)
        if (flags & EMIT_CLUSTERS_LAST)
            emit_clusters(job, sg, flags);
        gvrender_begin_cluster(job, sg);
-
-       url = tooltip = target = NULL;
-       explicit_tooltip = 0;
-
-       if (((s = agget(sg, "href")) && s[0]) || ((s = agget(sg, "URL")) && s[0]))
-           url = strdup_and_subst_graph(s, sg);
-
-       if ((s = agget(sg, "target")) && s[0])
-           target = strdup_and_subst_graph(s, sg);
-       if ((s = agget(sg, "tooltip")) && s[0]) {
-           tooltip = strdup_and_subst_graph(s, sg);
-           explicit_tooltip++;
-       } else if (GD_label(sg)) {
-           tooltip = strdup_and_subst_graph(GD_label(sg)->text, sg);
-       }
-       if (url || explicit_tooltip)
-           gvrender_begin_anchor(job, url, tooltip, target);
-
        setColorScheme (agget (sg, "colorscheme"));
        gvrender_begin_context(job);
        filled = FALSE;
@@ -1619,14 +1539,7 @@ void emit_clusters(GVJ_t * job, Agraph_t * g, int flags)
                    emit_edge(job, e);
            }
        }
-
        gvrender_end_context(job);
-       if (url || explicit_tooltip)
-           gvrender_end_anchor(job);
-
-       free(url);
-       free(tooltip);
-       free(target);
        gvrender_end_cluster(job, g);
        /* when drawing, lay down clusters before sub_clusters */
        if (!(flags & EMIT_CLUSTERS_LAST))
index 3692b03e0b7eadce01855699e30c1815d8cbcb53..4147a58e0717922a02f6d7a75448dd5b948f8dde 100644 (file)
@@ -137,28 +137,58 @@ static int ifFilled(node_t * n)
 }
 
 #if ! NEWANCHORS
-static void mapOutput (char* shapename, point* pp, int nump,
+static void mapOutput (map_shape_t map_shape, point* pp, int nump,
                char* url, char *target, char *label, char *tooltip)
 {
     int i;
 
     if (Output_lang == IMAP && url && url[0]) {
-       fprintf(Output_file, "%s %s ", shapename, url);
-       if (strcmp(shapename, "circle") == 0)
-           fprintf(Output_file, "%d,%d %d,%d", 
+       switch (map_shape) {
+       case MAP_RECTANGLE:
+           fprintf(Output_file, "rectangle %s %d %d %d %d\n", url,
+               pp[0].x, pp[0].y, pp[1].x, pp[1].y);
+           break;
+       case MAP_CIRCLE:
+           fprintf(Output_file, "circle %s %d %d %d %d\n", url,
                pp[0].x, pp[0].y, (pp[1].x+pp[0].x), pp[0].y);
-       else {
+           break;
+       case MAP_POLYGON:
+           fprintf(Output_file, "poly %s", url);
            for (i = 0; i < nump; i++)
-               fprintf(Output_file, "%d,%d ", pp[i].x, pp[i].y);
+               fprintf(Output_file, " %d,%d", pp[i].x, pp[i].y);
+           fprintf(Output_file, "\n");
+           break;
+       default:
+           assert(0);
+           break;
        }
-       fprintf(Output_file, "\n");
 
     } else if (Output_lang == ISMAP && url && url[0]) {
-       fprintf(Output_file, "rectangle (%d,%d) (%d,%d) %s %s\n",
+       switch (map_shape) {
+       case MAP_RECTANGLE:
+           fprintf(Output_file, "rectangle (%d,%d) (%d,%d) %s %s\n",
                pp[0].x, pp[0].y, pp[1].x, pp[1].y, url, label);
+           break;
+       default:
+           assert(0);
+           break;
+       }
 
     } else if (Output_lang == CMAP || Output_lang == CMAPX) {
-       fprintf(Output_file, "<area shape=\"%s\"", shapename);
+       switch (map_shape) {
+       case MAP_RECTANGLE:
+           fprintf(Output_file, "<area shape=\"rect\"");
+           break;
+       case MAP_CIRCLE:
+           fprintf(Output_file, "<area shape=\"circle\"");
+           break;
+       case MAP_POLYGON:
+           fprintf(Output_file, "<area shape=\"poly\"");
+           break;
+       default:
+           assert(0);
+           break;
+       }
        if (url && url[0])
            fprintf(Output_file, " href=\"%s\"", xml_string(url));
        if (target && target[0])
@@ -178,14 +208,22 @@ static void mapOutput (char* shapename, point* pp, int nump,
        fprintf(Output_file, " alt=\"\"");
        fprintf(Output_file, " coords=\"");
 
-       if (strcmp(shapename, "circle") == 0)
+       switch (map_shape) {
+       case MAP_RECTANGLE:
+           fprintf(Output_file, "%d,%d,%d,%d\"", pp[0].x, pp[0].y, pp[1].x, pp[1].y);
+           break;
+       case MAP_CIRCLE:
            fprintf(Output_file, "%d,%d,%d\"", pp[0].x, pp[0].y, pp[1].x);
-       else {
-           for (i = 0; i < nump; i++)
-               fprintf(Output_file, "%d,%d ", pp[i].x, pp[i].y);
+           break;
+       case MAP_POLYGON:
+           fprintf(Output_file, "%d,%d", pp[0].x, pp[0].y);
+           for (i = 1; i < nump; i++)
+               fprintf(Output_file, " %d,%d", pp[i].x, pp[i].y);
            fprintf(Output_file, "\"");
+           break;
+       default:
+           break;
        }
-
        if (Output_lang == CMAPX)
            fprintf(Output_file, " /");
        fprintf(Output_file, ">\n");
@@ -215,7 +253,7 @@ map_output_poly(node_t * n, char *url,
     int sides, peri, nump, i, j, filled = 0, rect = 0, nshape;
     pointf *ppf, *vertices, ldimen;
     point *pp, coord;
-    char *shapename;
+    map_shape_t map_shape;
     polygon_t *poly = NULL;
 
     /* checking shape of node */
@@ -256,7 +294,7 @@ map_output_poly(node_t * n, char *url,
         * when polygon has no peripheries and node is not filled 
         */
        if (poly->peripheries == 0 && !filled) {
-           shapename = "rect";
+           map_shape = MAP_RECTANGLE;
            nump = 2;
            ppf = N_NEW(nump, pointf);
            pp = N_NEW(nump, point);
@@ -271,7 +309,7 @@ map_output_poly(node_t * n, char *url,
        else if (poly->sides < 3 && poly->skew == 0.0
                    && poly->distortion == 0.0) {
            if (poly->regular) {
-               shapename = "circle";   /* circle */
+               map_shape = MAP_CIRCLE;
                nump = 2;               /* center of circle and radius */
                ppf = N_NEW(nump, pointf);
                pp = N_NEW(nump, point);
@@ -282,7 +320,7 @@ map_output_poly(node_t * n, char *url,
            }
            else { /* ellipse is treated as polygon */
                double a, b;
-               shapename = "poly";     /* ellipse */
+               map_shape = MAP_POLYGON;
                a = vertices[peri - 1].x;
                b = vertices[peri - 1].y;
                nump = sample;
@@ -296,7 +334,7 @@ map_output_poly(node_t * n, char *url,
            /* all other polygonal shape */
        } else {
            int offset = (peri - 1)*(poly->sides);
-           shapename = "poly";
+           map_shape = MAP_POLYGON;
            /* distorted or skewed ellipses and circles are polygons with 120 
              * sides. For mapping we convert them into polygon with sample sides
             */
@@ -324,7 +362,7 @@ map_output_poly(node_t * n, char *url,
         * when requested output format is neither imap nor cmapx and for all 
         * node shapes other than polygon ( except regular rectangle polygon ) 
         */
-       shapename = "rect";
+       map_shape = MAP_RECTANGLE;
        nump = 2;
        ppf = N_NEW(nump, pointf);
        pp = N_NEW(nump, point);
@@ -349,7 +387,7 @@ map_output_poly(node_t * n, char *url,
     }
 
 #if ! NEWANCHORS
-    mapOutput (shapename, pp, nump, url, target, label, tooltip);
+    mapOutput (map_shape, pp, nump, url, target, label, tooltip);
 #endif
     free(ppf);
     free(pp);
@@ -397,7 +435,7 @@ map_output_rect(pointf p1, pointf p2, char *url, char *target, char *label,
        pp[0].y = t;
     }
 #if ! NEWANCHORS
-    mapOutput ("rect", pp, 2, url, target, label, tooltip);
+    mapOutput (MAP_RECTANGLE, pp, 2, url, target, label, tooltip);
 #endif
 }
 
@@ -753,7 +791,7 @@ map_bspline_poly(int n, pointf* p1, pointf* p2,
        rp[last-i].x = ROUND(ppf.x);
        rp[last-i].y = ROUND(ppf.y);
     }
-    mapOutput ("poly", rp, last+1, url, target, NULL, tooltip);
+    mapOutput (MAP_POLYGON, rp, last+1, url, target, NULL, tooltip);
 #ifdef DEBUG
     psmapOutput (rp, last+1);
 #endif
index f7678ef911ad9703ed38e6cce3d0442d81bdcec3..8b90311a1d73ca7ba83ed1565eb22fec92de4ffb 100644 (file)
@@ -63,13 +63,14 @@ extern "C" {
 #define GVRENDER_DOES_TRANSFORM (1<<11)
 #define GVRENDER_DOES_LABELS (1<<12)
 #define GVRENDER_DOES_MAPS (1<<13)
-#define GVRENDER_DOES_MAP_RECT (1<<14)
-#define GVRENDER_DOES_MAP_ELLIPSE (1<<15)
-#define GVRENDER_DOES_MAP_POLY (1<<16)
-#define GVRENDER_DOES_MAP_BSPLINE (1<<17)
-#define GVRENDER_DOES_TOOLTIPS (1<<18)
-#define GVRENDER_DOES_TARGETS (1<<19)
-#define GVRENDER_DOES_Z (1<<20)
+#define GVRENDER_DOES_MAP_RECTANGLE (1<<14)
+#define GVRENDER_DOES_MAP_CIRCLE (1<<15)
+#define GVRENDER_DOES_MAP_POLYGON (1<<16)
+#define GVRENDER_DOES_MAP_ELLIPSE (1<<17)
+#define GVRENDER_DOES_MAP_BSPLINE (1<<18)
+#define GVRENDER_DOES_TOOLTIPS (1<<19)
+#define GVRENDER_DOES_TARGETS (1<<20)
+#define GVRENDER_DOES_Z (1<<21)
 
     typedef struct {
        int flags;
@@ -133,6 +134,8 @@ extern "C" {
        gvevent_key_callback_t callback;
     } gvevent_key_binding_t;
 
+    typedef enum {MAP_RECTANGLE, MAP_CIRCLE, MAP_POLYGON, } map_shape_t;
+
     typedef struct obj_state_s obj_state_t;
 
     struct obj_state_s {
@@ -157,13 +160,16 @@ extern "C" {
        char *tooltip;          /* if GVRENDER_DOES_TOOLTIPS */
        char *tailtooltip;
        char *headtooltip; 
+       bool explicit_tooltip;
+       bool explicit_tailtooltip;
+       bool explicit_headtooltip;
 
        char *target;           /* if GVRENDER_DOES_TARGETS */
        char *tailtarget;
        char *headtarget; 
 
        /* primary mapped region - node shape, edge label */
-       char *url_map_shapename;        /* "rect", "poly", "circle" */
+       map_shape_t url_map_shape; 
        int url_map_n;                  /* number of points for url map if GVRENDER_DOES_MAPS */
        pointf *url_map_p;
 
index d1d9ada7437eaa727cc2e4bb734b1b284b53ee74..3eb46883872323cf1e650ade42072df2ca72ba70 100644 (file)
@@ -338,6 +338,14 @@ static int gvrender_comparestr(const void *s1, const void *s2)
     return strcmp(*(char **) s1, *(char **) s2);
 }
 
+static void rect2poly(pointf *p)
+{
+    p[3].x = p[2].x = p[1].x;
+    p[2].y = p[1].y;
+    p[3].y = p[0].y;
+    p[1].x = p[0].x;
+}
+
 static void gvrender_resolve_color(gvrender_features_t * features,
                                   char *name, gvcolor_t * color)
 {
@@ -468,8 +476,37 @@ void gvrender_end_graph(GVJ_t * job)
 void gvrender_begin_page(GVJ_t * job)
 {
     gvrender_engine_t *gvre = job->render.engine;
+    obj_state_t *obj = job->obj;
+    int nump = 0, flags = job->flags;
+    pointf *p = NULL;
+
+    if (flags & (GVRENDER_DOES_MAPS | GVRENDER_DOES_TOOLTIPS)) {
+        if (flags & (GVRENDER_DOES_MAP_RECTANGLE | GVRENDER_DOES_MAP_POLYGON)) {
+           if (flags & GVRENDER_DOES_MAP_RECTANGLE) {
+               obj->url_map_shape = MAP_RECTANGLE;
+               nump = 2;
+           }
+           else {
+               obj->url_map_shape = MAP_POLYGON;
+               nump = 4;
+           }
+
+           p = N_NEW(nump, pointf);
+           p[0] = job->pageBox.LL;
+           p[1] = job->pageBox.UR;
+
+           if (! (flags & (GVRENDER_DOES_MAP_RECTANGLE)))
+               rect2poly(p);
+       }
+       if (! (flags & GVRENDER_DOES_TRANSFORM))
+           gvrender_ptf_A(job, p, p, nump);
+       obj->url_map_p = p;
+       obj->url_map_n = nump;
+    }
 
     if (gvre) {
+       if (gvre->begin_anchor && (obj->url || obj->explicit_tooltip))
+           gvre->begin_anchor(job, obj->url, obj->tooltip, obj->target);
         if (gvre->begin_page)
            gvre->begin_page(job);
     }
@@ -479,6 +516,8 @@ void gvrender_begin_page(GVJ_t * job)
         point offset;
 
         PF2P(job->pageOffset, offset);
+       if (cg && cg->begin_anchor && (obj->url || obj->explicit_tooltip))
+           cg->begin_anchor(obj->url, obj->tooltip, obj->target);
         if (cg && cg->begin_page)
             cg->begin_page(job->gvc->g, job->pagesArrayElem,
                job->zoom, job->rotation, offset);
@@ -489,10 +528,13 @@ void gvrender_begin_page(GVJ_t * job)
 void gvrender_end_page(GVJ_t * job)
 {
     gvrender_engine_t *gvre = job->render.engine;
+    obj_state_t *obj = job->obj;
 
     if (gvre) {
                if (gvre->end_page)
            gvre->end_page(job);
+       if (gvre->end_anchor && (obj->url || obj->explicit_tooltip))
+           gvre->end_anchor(job);
     }
 #ifdef WITH_CODEGENS
     else {
@@ -500,6 +542,8 @@ void gvrender_end_page(GVJ_t * job)
 
        if (cg && cg->end_page)
            cg->end_page();
+       if (cg && cg->end_anchor && (obj->url || obj->explicit_tooltip))
+           cg->end_anchor();
     }
 #endif
 }
@@ -540,14 +584,6 @@ void gvrender_end_layer(GVJ_t * job)
 #endif
 }
 
-static void rect2poly(pointf *p)
-{
-    p[3].x = p[2].x = p[1].x;
-    p[2].y = p[1].y;
-    p[3].y = p[0].y;
-    p[1].x = p[0].x;
-}
-
 void gvrender_begin_cluster(GVJ_t * job, graph_t * sg)
 {
     gvrender_engine_t *gvre = job->render.engine;
@@ -576,13 +612,13 @@ void gvrender_begin_cluster(GVJ_t * job, graph_t * sg)
         obj->tooltip = strdup_and_subst_graph(s, sg);
 
     if (flags & (GVRENDER_DOES_MAPS | GVRENDER_DOES_TOOLTIPS)) {
-        if (flags & (GVRENDER_DOES_MAP_RECT | GVRENDER_DOES_MAP_POLY)) {
-           if (flags & GVRENDER_DOES_MAP_RECT) {
-               obj->url_map_shapename = "rect";
+        if (flags & (GVRENDER_DOES_MAP_RECTANGLE | GVRENDER_DOES_MAP_POLYGON)) {
+           if (flags & GVRENDER_DOES_MAP_RECTANGLE) {
+               obj->url_map_shape = MAP_RECTANGLE;
                nump = 2;
            }
            else {
-               obj->url_map_shapename = "poly";
+               obj->url_map_shape = MAP_POLYGON;
                nump = 4;
            }
 
@@ -590,7 +626,7 @@ void gvrender_begin_cluster(GVJ_t * job, graph_t * sg)
            P2PF(GD_bb(sg).LL, p[0]);
            P2PF(GD_bb(sg).UR, p[1]);
 
-           if (! (flags & (GVRENDER_DOES_MAP_RECT)))
+           if (! (flags & (GVRENDER_DOES_MAP_RECTANGLE)))
                rect2poly(p);
        }
        obj->url_map_p = p;
@@ -598,6 +634,8 @@ void gvrender_begin_cluster(GVJ_t * job, graph_t * sg)
     }
 
     if (gvre) {
+       if (gvre->begin_anchor && (obj->url || obj->explicit_tooltip))
+           gvre->begin_anchor(job, obj->url, obj->tooltip, obj->target);
        if (gvre->begin_cluster)
            gvre->begin_cluster(job);
     }
@@ -606,6 +644,8 @@ void gvrender_begin_cluster(GVJ_t * job, graph_t * sg)
        codegen_t *cg = job->codegen;
 
         Obj = CLST;
+       if (cg && cg->begin_anchor && (obj->url || obj->explicit_tooltip))
+           cg->begin_anchor(obj->url, obj->tooltip, obj->target);
        if (cg && cg->begin_cluster)
            cg->begin_cluster(sg);
     }
@@ -615,10 +655,13 @@ void gvrender_begin_cluster(GVJ_t * job, graph_t * sg)
 void gvrender_end_cluster(GVJ_t * job, graph_t *g)
 {
     gvrender_engine_t *gvre = job->render.engine;
+    obj_state_t *obj = job->obj;
 
     if (gvre) {
                if (gvre->end_cluster)
            gvre->end_cluster(job);
+       if (gvre->end_anchor && (obj->url || obj->explicit_tooltip))
+           gvre->end_anchor(job);
     }
 #ifdef WITH_CODEGENS
     else {
@@ -626,6 +669,8 @@ void gvrender_end_cluster(GVJ_t * job, graph_t *g)
 
        if (cg && cg->end_cluster)
            cg->end_cluster();
+       if (cg && cg->end_anchor && (obj->url || obj->explicit_tooltip))
+           cg->end_anchor();
     }
     Obj = NONE;
 #endif
@@ -758,7 +803,7 @@ void gvrender_begin_node(GVJ_t * job, node_t * n)
     gvrender_engine_t *gvre = job->render.engine;
     obj_state_t *obj;
     textlabel_t *lab;
-    int flags, sides, peripheries, i, j, filled = 0, rect = 0, shape, sample = 100, nump = 0;
+    int flags, sides, peripheries, i, j, filled = 0, rect = 0, shape, nump = 0;
     polygon_t *poly = NULL;
     pointf *vertices, ldimen, *p =  NULL;
     point coord;
@@ -780,15 +825,15 @@ void gvrender_begin_node(GVJ_t * job, node_t * n)
         && (((s = agget(n, "href")) && s[0]) || ((s = agget(n, "URL")) && s[0]))) {
         obj->url = strdup_and_subst_node(s, n);
     }
-    if ((flags & GVRENDER_DOES_TARGETS) && ((s = agget(n, "target")) && s[0])) {
-        obj->target = strdup_and_subst_node(s, n);
-    }
     if (flags & GVRENDER_DOES_TOOLTIPS) {
         if ((s = agget(n, "tooltip")) && s[0])
             obj->tooltip = strdup_and_subst_node(s, n);
        else
            obj->tooltip = strdup(ND_label(n)->text);
     } 
+    if ((flags & GVRENDER_DOES_TARGETS) && ((s = agget(n, "target")) && s[0])) {
+        obj->target = strdup_and_subst_node(s, n);
+    }
     if (flags & (GVRENDER_DOES_MAPS | GVRENDER_DOES_TOOLTIPS)) {
 
         /* checking shape of node */
@@ -811,7 +856,7 @@ void gvrender_begin_node(GVJ_t * job, node_t * n)
          * circle, ellipse, polygon with n side, or point.
          * For regular rectangular shape we have use node's bounding box to map clickable region
          */
-        if (poly && !rect && (flags & GVRENDER_DOES_MAP_POLY)) {
+        if (poly && !rect && (flags & GVRENDER_DOES_MAP_POLYGON)) {
 
             if (poly->sides < 3)
                 sides = 1;
@@ -825,11 +870,19 @@ void gvrender_begin_node(GVJ_t * job, node_t * n)
 
             vertices = poly->vertices;
 
+           if ((s = agget(n, "samplepoints")))
+               nump = atoi(s);
+           /* We want at least 4 points. For server-side maps, at most 100
+            * points are allowed. To simplify things to fit with the 120 points
+            * used for skewed ellipses, we set the bound at 60.
+            */
+           if ((nump < 4) || (nump > 60))
+               nump = DFLT_SAMPLE;
             /* use bounding box of text label for mapping
             * when polygon has no peripheries and node is not filled
             */
             if (poly->peripheries == 0 && !filled) {
-                obj->url_map_shapename = "rect";
+                obj->url_map_shape = MAP_RECTANGLE;
                 nump = 2;
                 p = N_NEW(nump, pointf);
                 ldimen = ND_label(n)->dimen;
@@ -838,7 +891,7 @@ void gvrender_begin_node(GVJ_t * job, node_t * n)
             /* circle or ellipse */
             else if (poly->sides < 3 && poly->skew == 0.0 && poly->distortion == 0.0) {
                 if (poly->regular) {
-                    obj->url_map_shapename = "circle";   /* circle */
+                    obj->url_map_shape = MAP_CIRCLE;
                     nump = 2;              /* center of circle and top right corner of bb */
                     p = N_NEW(nump, pointf);
                     p[0].x = coord.x;
@@ -847,11 +900,9 @@ void gvrender_begin_node(GVJ_t * job, node_t * n)
                     p[1].y = coord.y + vertices[peripheries - 1].y;
                 }
                 else { /* ellipse is treated as polygon */
-                    obj->url_map_shapename = "poly";     /* ellipse */
-                    nump = sample;
+                    obj->url_map_shape= MAP_POLYGON;
                     p = pEllipse((double)(vertices[peripheries - 1].x),
-                                             (double)(vertices[peripheries - 1].y),
-                                             nump);
+                                (double)(vertices[peripheries - 1].y), nump);
                     for (i = 0; i < nump; i++) {
                         p[i].x += coord.x;
                         p[i].y += coord.y;
@@ -861,13 +912,12 @@ void gvrender_begin_node(GVJ_t * job, node_t * n)
             /* all other polygonal shape */
            else {
                 int offset = (peripheries - 1)*(poly->sides);
-                obj->url_map_shapename = "poly";
+                obj->url_map_shape = MAP_POLYGON;
                 /* distorted or skewed ellipses and circles are polygons with 120
                 * sides. For mapping we convert them into polygon with sample sides
                 */
-                if (poly->sides >= sample) {
-                    int delta = poly->sides / sample;
-                    nump = sample;
+                if (poly->sides >= nump) {
+                    int delta = poly->sides / nump;
                     p = N_NEW(nump, pointf);
                     for (i = 0, j = 0; j < nump; i += delta, j++) {
                         p[j].x = coord.x + vertices[i + offset].x;
@@ -887,7 +937,7 @@ void gvrender_begin_node(GVJ_t * job, node_t * n)
             /* we have to use the node's bounding box to map clickable region
             * when requested output format is not capable of polygons.
             */
-            obj->url_map_shapename = "rect";
+            obj->url_map_shape = MAP_RECTANGLE;
             nump = 2;
             p = N_NEW(nump, pointf);
             p[0].x = coord.x - ND_lw_i(n);
@@ -895,11 +945,15 @@ void gvrender_begin_node(GVJ_t * job, node_t * n)
             p[1].x = coord.x + ND_rw_i(n);
             p[1].y = coord.y + (ND_ht_i(n) / 2);
         }
+       if (! (flags & GVRENDER_DOES_TRANSFORM))
+           gvrender_ptf_A(job, p, p, nump);
        obj->url_map_p = p;
        obj->url_map_n = nump;
     }
 
     if (gvre) {
+       if (gvre->begin_anchor && (obj->url || obj->explicit_tooltip))
+           gvre->begin_anchor(job, obj->url, obj->tooltip, obj->target);
        if (gvre->begin_node)
            gvre->begin_node(job);
     }
@@ -908,6 +962,8 @@ void gvrender_begin_node(GVJ_t * job, node_t * n)
        codegen_t *cg = job->codegen;
 
         Obj = NODE;
+       if (cg && cg->begin_anchor && (obj->url || obj->explicit_tooltip))
+           cg->begin_anchor(obj->url, obj->tooltip, obj->target);
        if (cg && cg->begin_node)
            cg->begin_node(n);
     }
@@ -917,10 +973,13 @@ void gvrender_begin_node(GVJ_t * job, node_t * n)
 void gvrender_end_node(GVJ_t * job)
 {
     gvrender_engine_t *gvre = job->render.engine;
+    obj_state_t *obj = job->obj;
 
     if (gvre) {
        if (gvre->end_node)
            gvre->end_node(job);
+       if (gvre->end_anchor && (obj->url || obj->explicit_tooltip))
+           gvre->end_anchor(job);
     }
 #ifdef WITH_CODEGENS
     else {
@@ -928,6 +987,8 @@ void gvrender_end_node(GVJ_t * job)
 
        if (cg && cg->end_node)
            cg->end_node();
+       if (cg && cg->end_anchor && (obj->url || obj->explicit_tooltip))
+           cg->end_anchor();
     }
     Obj = NONE;
 #endif
@@ -986,15 +1047,15 @@ static segitem_t* appendSeg (pointf p, segitem_t* lp)
  */
 static void map_bspline_poly(pointf **pbs_p, int **pbs_n, int *pbs_poly_n, int n, pointf* p1, pointf* p2) 
 {
-    int i, nump = 0, last = 2*n-1;
+    int i = 0, nump = 0, last = 2*n-1;
 
-    for ( i = 0; i < *pbs_poly_n; i++)
+    for ( ; i < *pbs_poly_n; i++)
        nump += (*pbs_n)[i];
 
     (*pbs_poly_n)++;
     *pbs_n = grealloc(*pbs_n, (*pbs_poly_n) * sizeof(int));
-    (*pbs_n)[i] = n;
-    *pbs_p = grealloc(*pbs_p, (nump + n) * sizeof(pointf));
+    (*pbs_n)[i] = 2*n;
+    *pbs_p = grealloc(*pbs_p, (nump + 2*n) * sizeof(pointf));
 
     for (i = 0; i < n; i++) {
        (*pbs_p)[nump+i] = p1[i];
@@ -1183,7 +1244,7 @@ void gvrender_begin_edge(GVJ_t * job, edge_t * e)
        }
     }
 
-    if (flags & (GVRENDER_DOES_MAPS | GVRENDER_DOES_TOOLTIPS)) {
+    if (flags & GVRENDER_DOES_MAPS) {
         if (((s = agget(e, "href")) && s[0]) || ((s = agget(e, "URL")) && s[0]))
             obj->url = strdup_and_subst_edge(s, e);
        if (((s = agget(e, "tailhref")) && s[0]) || ((s = agget(e, "tailURL")) && s[0]))
@@ -1210,28 +1271,34 @@ void gvrender_begin_edge(GVJ_t * job, edge_t * e)
     } 
 
     if (flags & GVRENDER_DOES_TOOLTIPS) {
-        if ((s = agget(e, "tooltip")) && s[0])
+        if ((s = agget(e, "tooltip")) && s[0]) {
             obj->tooltip = strdup_and_subst_edge(s, e);
+           obj->explicit_tooltip = true;
+       }
        else if (obj->label)
            obj->tooltip = strdup(obj->label);
-        if ((s = agget(e, "tailtooltip")) && s[0])
+        if ((s = agget(e, "tailtooltip")) && s[0]) {
             obj->tailtooltip = strdup_and_subst_edge(s, e);
+           obj->explicit_tailtooltip = true;
+       }
        else if (obj->taillabel)
            obj->tailtooltip = strdup(obj->taillabel);
-        if ((s = agget(e, "headtooltip")) && s[0])
+        if ((s = agget(e, "headtooltip")) && s[0]) {
             obj->headtooltip = strdup_and_subst_edge(s, e);
+           obj->explicit_headtooltip = true;
+       }
        else if (obj->headlabel)
            obj->headtooltip = strdup(obj->headlabel);
     } 
 
     if (flags & (GVRENDER_DOES_MAPS | GVRENDER_DOES_TOOLTIPS)) {
-        if (flags & (GVRENDER_DOES_MAP_RECT | GVRENDER_DOES_MAP_POLY)) {
-            if (flags & GVRENDER_DOES_MAP_RECT) {
-               obj->url_map_shapename = "rect";
+        if (flags & (GVRENDER_DOES_MAP_RECTANGLE | GVRENDER_DOES_MAP_POLYGON)) {
+            if (flags & GVRENDER_DOES_MAP_RECTANGLE) {
+               obj->url_map_shape = MAP_RECTANGLE;
                nump = 2;
            }
-           else { /* GVRENDER_DOES_MAP_POLY */
-               obj->url_map_shapename = "poly";
+           else { /* GVRENDER_DOES_MAP_POLYGON */
+               obj->url_map_shape = MAP_POLYGON;
                nump = 4;
            }
 
@@ -1281,7 +1348,7 @@ void gvrender_begin_edge(GVJ_t * job, edge_t * e)
                 }
             }
 
-           if (ED_spl(e) && (obj->url || obj->tooltip) && (flags & GVRENDER_DOES_MAP_POLY)) {
+           if (ED_spl(e) && (obj->url || obj->tooltip) && (flags & GVRENDER_DOES_MAP_POLYGON)) {
                int ns;
                splines *spl;
 
@@ -1305,7 +1372,7 @@ void gvrender_begin_edge(GVJ_t * job, edge_t * e)
                    gvrender_ptf_A(job, pbs, pbs, nump);                
                }
            }
-           if (! (flags & GVRENDER_DOES_MAP_RECT)) {
+           if (! (flags & GVRENDER_DOES_MAP_RECTANGLE)) {
                if (p) rect2poly(p);
                if (pt) rect2poly(pt);
                if (ph) rect2poly(ph);
@@ -1323,6 +1390,8 @@ void gvrender_begin_edge(GVJ_t * job, edge_t * e)
     }
 
     if (gvre) {
+       if (gvre->begin_anchor && (obj->url || obj->explicit_tooltip))
+           gvre->begin_anchor(job, obj->url, obj->tooltip, obj->target);
        if (gvre->begin_edge)
            gvre->begin_edge(job);
     }
@@ -1331,6 +1400,8 @@ void gvrender_begin_edge(GVJ_t * job, edge_t * e)
        codegen_t *cg = job->codegen;
 
         Obj = EDGE;
+       if (cg && cg->begin_anchor && (obj->url || obj->explicit_tooltip))
+           cg->begin_anchor(obj->url, obj->tooltip, obj->target);
        if (cg && cg->begin_edge)
            cg->begin_edge(e);
     }
@@ -1340,10 +1411,13 @@ void gvrender_begin_edge(GVJ_t * job, edge_t * e)
 void gvrender_end_edge(GVJ_t * job)
 {
     gvrender_engine_t *gvre = job->render.engine;
+    obj_state_t *obj = job->obj;
 
     if (gvre) {
        if (gvre->end_edge)
            gvre->end_edge(job);
+       if (gvre->end_anchor && (obj->url || obj->explicit_tooltip))
+           gvre->end_anchor(job);
     }
 #ifdef WITH_CODEGENS
     else {
@@ -1351,6 +1425,8 @@ void gvrender_end_edge(GVJ_t * job)
 
        if (cg && cg->end_edge)
            cg->end_edge();
+       if (cg && cg->end_anchor && (obj->url || obj->explicit_tooltip))
+           cg->end_anchor();
     }
     Obj = NONE;
 #endif
@@ -1398,8 +1474,7 @@ void gvrender_end_context(GVJ_t * job)
 #endif
 }
 
-void gvrender_begin_anchor(GVJ_t * job, char *href, char *tooltip,
-                          char *target)
+void gvrender_begin_anchor(GVJ_t * job, char *href, char *tooltip, char *target)
 {
     gvrender_engine_t *gvre = job->render.engine;
 
index d3bbd8bcb8c89fa374f8ab75f42265b5d6cbce52..d0ccb19278170ca42822a4f1ae87fe6430c1d80a 100644 (file)
@@ -30,6 +30,9 @@
 
 #include "gvplugin_loadimage.h"
 
+/* for n->name */
+#include "graph.h"
+
 extern void svggen_fputs(GVJ_t * job, char *s);
 extern void svggen_printf(GVJ_t * job, const char *format, ...);
 
@@ -38,6 +41,7 @@ extern shape_desc *find_user_shape(char *name);
 
 typedef enum {
     FORMAT_PNG_SVG, FORMAT_GIF_SVG, FORMAT_JPEG_SVG,
+    FORMAT_PNG_VRML, FORMAT_GIF_VRML, FORMAT_JPEG_VRML,
     FORMAT_PS_PS, FORMAT__PS,
 } format_type;
 
@@ -63,6 +67,39 @@ static void core_loadimage_svg(GVJ_t * job, usershape_t *us, boxf b, bool filled
     svggen_fputs(job, "/>\n");
 }
 
+static void core_loadimage_vrml(GVJ_t * job, usershape_t *us, boxf b, bool filled)
+{
+    FILE *out;
+    obj_state_t *obj;
+    node_t *n;
+
+    assert(job);
+
+    out = job->output_file;
+    obj = job->obj;
+    assert(out);
+    assert(obj);
+
+    assert(us);
+    assert(us->name);
+    assert(us->f);
+
+    n = job->obj->n;
+    assert(n);
+
+    fprintf(out, "Shape {\n");
+    fprintf(out, "  appearance Appearance {\n");
+    fprintf(out, "    material Material {\n");
+    fprintf(out, "      ambientIntensity 0.33\n");
+    fprintf(out, "        diffuseColor 1 1 1\n");
+    fprintf(out, "    }\n");
+    fprintf(out, "    texture ImageTexture { url \"%s\" }\n", us->name);
+    fprintf(out, "  }\n");
+    fprintf(out, "}\n");
+
+
+}
+
 static void ps_freeimage(usershape_t *us)
 {
 #if HAVE_SYS_MMAN_H
@@ -175,6 +212,10 @@ static gvloadimage_engine_t engine_svg = {
     core_loadimage_svg
 };
 
+static gvloadimage_engine_t engine_vrml = {
+    core_loadimage_vrml
+};
+
 static gvloadimage_engine_t engine_ps = {
     core_loadimage_ps
 };
@@ -187,6 +228,9 @@ gvplugin_installed_t gvloadimage_core_types[] = {
     {FORMAT_PNG_SVG, "png2svg", 1, &engine_svg, NULL},
     {FORMAT_GIF_SVG, "gif2svg", 1, &engine_svg, NULL},
     {FORMAT_JPEG_SVG, "jpeg2svg", 1, &engine_svg, NULL},
+    {FORMAT_PNG_VRML, "png2vrml", 1, &engine_vrml, NULL},
+    {FORMAT_GIF_VRML, "gif2vrml", 1, &engine_vrml, NULL},
+    {FORMAT_JPEG_VRML, "jpeg2vrml", 1, &engine_vrml, NULL},
     {FORMAT_PS_PS, "ps2ps", 1, &engine_ps, NULL},
     {FORMAT__PS, "2ps", 1, &engine_pslib, NULL},
     {0, NULL, 0, NULL, NULL}
index c206298b9feef6c5a0b5cf6b10748e662a50002e..3e9ef54035e2a6ca1b6fd725f43259a64664cc73 100644 (file)
@@ -31,7 +31,114 @@ extern char *xml_string(char *str);
 
 typedef enum { FORMAT_IMAP, FORMAT_ISMAP, FORMAT_CMAP, FORMAT_CMAPX, } format_type;
 
-static void mapgen_begin_job(GVJ_t * job)
+static void map_output_shape (GVJ_t *job, map_shape_t map_shape, pointf * AF, int nump,
+                char* url, char *tooltip, char *target)
+{
+    FILE *out = job->output_file;
+    int i;
+
+    static point *A;
+    static int size_A;
+
+    if (size_A < nump) {
+       size_A = nump + 10;
+       A = realloc(A, size_A * sizeof(point));
+    }
+    for (i = 0; i < nump; i++)
+       PF2P(AF[i], A[i]);
+
+    if (job->render.id == FORMAT_IMAP) {
+        switch (map_shape) {
+        case MAP_RECTANGLE:
+           /* Y_GOES_DOWN so need UL to LR */
+            fprintf(out, "rect %s %d %d %d %d\n", url,
+                A[0].x, A[1].y, A[1].x, A[0].y);
+            break;
+        case MAP_CIRCLE:
+            fprintf(out, "circle %s %d %d %d %d\n", url,
+                A[0].x, A[0].y, (A[1].x+A[0].x), A[0].y);
+            break;
+        case MAP_POLYGON:
+            fprintf(out, "poly %s", url);
+            for (i = 0; i < nump; i++)
+                fprintf(out, " %d,%d", A[i].x, A[i].y);
+            fprintf(out, "\n");
+            break;
+        default:
+            assert(0);
+            break;
+        }
+
+    } else if (job->render.id == FORMAT_ISMAP) {
+        switch (map_shape) {
+        case MAP_RECTANGLE:
+           /* Y_GOES_DOWN so need UL to LR */
+            fprintf(out, "rectangle (%d,%d) (%d,%d) %s %s\n",
+                A[0].x, A[1].y, A[1].x, A[0].y, url, tooltip);
+           break;
+        default:
+            assert(0);
+            break;
+        }
+
+    } else if (job->render.id == FORMAT_CMAP || job->render.id == FORMAT_CMAPX) {
+        switch (map_shape) {
+        case MAP_CIRCLE:
+            fprintf(out, "<area shape=\"circle\"");
+            break;
+        case MAP_RECTANGLE:
+            fprintf(out, "<area shape=\"rect\"");
+            break;
+        case MAP_POLYGON:
+            fprintf(out, "<area shape=\"poly\"");
+            break;
+        default:
+            assert(0);
+            break;
+        }
+        if (url && url[0])
+            fprintf(out, " href=\"%s\"", xml_string(url));
+        if (target && target[0])
+            fprintf(out, " target=\"%s\"", xml_string(target));
+        if (tooltip && tooltip[0])
+            fprintf(out, " title=\"%s\"", xml_string(tooltip));
+        /*
+        * alt text is intended for the visually impaired, but such
+        * folk are not likely to be clicking around on a graph anyway.
+        * IE on the PC platform (but not on Macs) incorrectly
+        * uses (non-empty) alt strings instead of title strings for tooltips.
+        * To make tooltips work and avoid this IE issue,
+        * while still satisfying usability guidelines
+        * that require that there is always an alt string,
+        * we generate just an empty alt string.
+        */
+        fprintf(out, " alt=\"\"");
+
+        fprintf(out, " coords=\"");
+        switch (map_shape) {
+        case MAP_CIRCLE:
+            fprintf(out, "%d,%d,%d", A[0].x, A[0].y, A[1].x);
+            break;
+        case MAP_RECTANGLE:
+           /* Y_GOES_DOWN so need UL to LR */
+            fprintf(out, "%d,%d,%d,%d", A[0].x, A[1].y, A[1].x, A[0].y);  
+            break;
+        case MAP_POLYGON:
+            fprintf(out, "%d,%d", A[0].x, A[0].y);
+            for (i = 1; i < nump; i++)
+                fprintf(out, " %d,%d", A[i].x, A[i].y);
+            break;
+        default:
+            break;
+        }
+        if (job->render.id == FORMAT_CMAPX)
+            fprintf(out, "\"/>\n");
+       else
+            fprintf(out, "\">\n");
+    }
+}
+
+static void map_begin_job(GVJ_t * job)
 {
     switch (job->render.id) {
     case FORMAT_IMAP:
@@ -42,40 +149,37 @@ static void mapgen_begin_job(GVJ_t * job)
     }
 }
 
-static void mapgen_begin_page(GVJ_t * job)
+static void map_begin_page(GVJ_t * job)
 {
     obj_state_t *obj = job->obj;
     char *name = xml_string(obj->g->name);
 
     switch (job->render.id) {
+    case FORMAT_IMAP:
+        if (obj->url)
+           fprintf(job->output_file, "default %s\n", obj->url);
+        break;
+    case FORMAT_ISMAP:
+        if (obj->url)
+           fprintf(job->output_file, "default %s %s\n", obj->url, obj->g->name);
+        break;
     case FORMAT_CMAPX:
        fprintf(job->output_file, "<map id=\"%s\" name=\"%s\">\n", name, name);
         break;
     default:
        break;
     }
-    if (obj->url) {
-        switch (job->render.id) {
-        case FORMAT_IMAP:
-           fprintf(job->output_file, "default %s\n", obj->url);
-            break;
-        case FORMAT_ISMAP:
-           fprintf(job->output_file, "default %s %s\n", obj->url, obj->g->name);
-            break;
-        case FORMAT_CMAP:
-        case FORMAT_CMAPX:
-       /* FIXME */
-            break;
-        default:
-           break;
-        }
-    }
 }
 
-static void mapgen_end_page(GVJ_t * job)
+static void map_end_page(GVJ_t * job)
 {
+    obj_state_t *obj = job->obj;
+
     switch (job->render.id) {
     case FORMAT_CMAPX:
+       if (obj->url_map_p)
+           map_output_shape(job, obj->url_map_shape, obj->url_map_p,obj->url_map_n,
+                                   obj->url, obj->tooltip, obj->target);
         fprintf(job->output_file, "</map>\n");
        break;
     default:
@@ -83,98 +187,98 @@ static void mapgen_end_page(GVJ_t * job)
     }
 }
 
-static void mapgen_begin_cluster(GVJ_t * job)
+static void map_begin_cluster(GVJ_t * job)
 {
     obj_state_t *obj = job->obj;
 
     fprintf(job->output_file, "%% %s\n", obj->sg->name);
 
-    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);
-    }
+    if (obj->url_map_p)
+        map_output_shape(job, obj->url_map_shape, obj->url_map_p, obj->url_map_n,
+               obj->url, obj->tooltip, obj->target);
 }
 
-static void mapgen_begin_node(GVJ_t * job)
+static void map_begin_node(GVJ_t * job)
 {
     obj_state_t *obj = job->obj;
 
-    if (obj->url_map_p) {
-        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);
-    }
+    if (obj->url_map_p)
+        map_output_shape(job, obj->url_map_shape, obj->url_map_p,obj->url_map_n,
+               obj->url, obj->tooltip, obj->target);
 }
 
 static void
-mapgen_begin_edge(GVJ_t * job)
+map_begin_edge(GVJ_t * job)
 {
     obj_state_t *obj = job->obj;
+    int i, j = 0;
 
-    if (obj->url_map_p) {
-        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);
-    }
-    if (obj->tailurl_map_p) {
-        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);
-    }
-    if (obj->headurl_map_p) {
-        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);
-    }
-    if (obj->tailendurl_map_p) {
-        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);
-    }
-    if (obj->headendurl_map_p) {
-        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);
+    if (obj->url_map_p)
+        map_output_shape(job, obj->url_map_shape, obj->url_map_p, obj->url_map_n,
+               obj->url, obj->tooltip, obj->target);
+
+    if (obj->tailurl_map_p)
+        map_output_shape(job, MAP_RECTANGLE, obj->tailurl_map_p, 2,
+               obj->tailurl, obj->tailtooltip, obj->tailtarget);
+    if (obj->headurl_map_p)
+        map_output_shape(job, MAP_RECTANGLE, obj->headurl_map_p, 2,
+               obj->headurl, obj->headtooltip, obj->headtarget);
+
+    if (obj->tailendurl_map_p)
+        map_output_shape(job, MAP_RECTANGLE, obj->tailendurl_map_p,2, 
+               obj->url, obj->tooltip, obj->target);
+    if (obj->headendurl_map_p)
+        map_output_shape(job, MAP_RECTANGLE, obj->headendurl_map_p, 2,
+               obj->url, obj->tooltip, obj->target);
+
+    for (i = 0; i < obj->url_bsplinemap_poly_n; i++) {
+        map_output_shape(job, MAP_POLYGON, obj->url_bsplinemap_p+j, obj->url_bsplinemap_n[i],
+                obj->url, obj->tooltip, obj->target);
+       j += obj->url_bsplinemap_n[i];
     }
 }
 
-static gvrender_engine_t mapgen_engine = {
-    mapgen_begin_job,
-    0,                         /* mapgen_end_job */
-    0,                         /* mapgen_begin_graph */
-    0,                         /* mapgen_end_graph */
-    0,                         /* mapgen_begin_layer */
-    0,                         /* mapgen_end_layer */
-    mapgen_begin_page,
-    mapgen_end_page,
-    mapgen_begin_cluster,
-    0,                         /* mapgen_end_cluster */
-    0,                         /* mapgen_begin_nodes */
-    0,                         /* mapgen_end_nodes */
-    0,                         /* mapgen_begin_edges */
-    0,                         /* mapgen_end_edges */
-    mapgen_begin_node,
-    0,                         /* mapgen_end_node */
-    mapgen_begin_edge,
-    0,                         /* mapgen_end_edge */
-    0,                         /* mapgen_begin_anchor */
-    0,                         /* mapgen_end_anchor */
-    0,                         /* mapgen_textpara */
-    0,                         /* mapgen_resolve_color */
-    0,                         /* mapgen_ellipse */
-    0,                         /* mapgen_polygon */
-    0,                         /* mapgen_bezier */
-    0,                         /* mapgen_polyline */
-    0,                         /* mapgen_comment */
+static gvrender_engine_t map_engine = {
+    map_begin_job,
+    0,                         /* map_end_job */
+    0,                         /* map_begin_graph */
+    0,                         /* map_end_graph */
+    0,                         /* map_begin_layer */
+    0,                         /* map_end_layer */
+    map_begin_page,
+    map_end_page,
+    map_begin_cluster,
+    0,                         /* map_end_cluster */
+    0,                         /* map_begin_nodes */
+    0,                         /* map_end_nodes */
+    0,                         /* map_begin_edges */
+    0,                         /* map_end_edges */
+    map_begin_node,
+    0,                         /* map_end_node */
+    map_begin_edge,
+    0,                         /* map_end_edge */
+    0,                         /* map_begin_anchor */
+    0,                         /* map_end_anchor */
+    0,                         /* map_textpara */
+    0,                         /* map_resolve_color */
+    0,                         /* map_ellipse */
+    0,                         /* map_polygon */
+    0,                         /* map_bezier */
+    0,                         /* map_polyline */
+    0,                         /* map_comment */
 };
 
-static gvrender_features_t mapgen_features_poly = {
-    GVRENDER_DOES_MAPS
-       | GVRENDER_DOES_MAP_RECT
-       | GVRENDER_DOES_MAP_POLY,
+static gvrender_features_t map_features_poly = {
+    GVRENDER_Y_GOES_DOWN
+       | GVRENDER_DOES_MAPS
+       | GVRENDER_DOES_LABELS
+       | GVRENDER_DOES_TOOLTIPS
+       | GVRENDER_DOES_TARGETS
+       | GVRENDER_DOES_MAP_RECTANGLE
+       | GVRENDER_DOES_MAP_CIRCLE
+       | GVRENDER_DOES_MAP_POLYGON,
     0,                         /* default margin - points */
-    {72.,72.},                 /* default dpi */
+    {96.,96.},                 /* default dpi */
     NULL,                      /* knowncolors */
     0,                         /* sizeof knowncolors */
     0,                         /* color_type */
@@ -182,11 +286,14 @@ static gvrender_features_t mapgen_features_poly = {
     NULL,                       /* gvloadimage target for usershapes */
 };
 
-static gvrender_features_t mapgen_features = {
-    GVRENDER_DOES_MAPS
-       | GVRENDER_DOES_MAP_RECT,
+static gvrender_features_t map_features = {
+    GVRENDER_Y_GOES_DOWN
+       | GVRENDER_DOES_MAPS
+       | GVRENDER_DOES_LABELS
+       | GVRENDER_DOES_TOOLTIPS
+       | GVRENDER_DOES_MAP_RECTANGLE,
     0,                         /* default margin - points */
-    {72.,72.},                 /* default dpi */
+    {96.,96.},                 /* default dpi */
     NULL,                      /* knowncolors */
     0,                         /* sizeof knowncolors */
     0,                         /* color_type */
@@ -195,9 +302,9 @@ static gvrender_features_t mapgen_features = {
 };
 
 gvplugin_installed_t gvrender_core_map_types[] = {
-    {FORMAT_IMAP, "imap", -1, &mapgen_engine, &mapgen_features_poly},
-    {FORMAT_ISMAP, "ismap", -1, &mapgen_engine, &mapgen_features},
-    {FORMAT_CMAP, "cmap", -1, &mapgen_engine, &mapgen_features},
-    {FORMAT_CMAPX, "cmapx", -1, &mapgen_engine, &mapgen_features_poly},
+    {FORMAT_ISMAP, "ismap", 1, &map_engine, &map_features},
+    {FORMAT_IMAP, "imap", 1, &map_engine, &map_features_poly},
+    {FORMAT_CMAP, "cmap", 1, &map_engine, &map_features_poly},
+    {FORMAT_CMAPX, "cmapx", 1, &map_engine, &map_features_poly},
     {0, NULL, 0, NULL, NULL}
 };
index f7869bae01b83d1653616f9ca5af09201d9d9627..edf403b560d6053d694223cb642a01d785068368 100644 (file)
@@ -465,7 +465,7 @@ static gvrender_features_t psgen_features = {
     GVRENDER_DOES_MULTIGRAPH_OUTPUT_FILES
        | GVRENDER_DOES_TRANSFORM
        | GVRENDER_DOES_MAPS
-       | GVRENDER_DOES_MAP_RECT,
+       | GVRENDER_DOES_MAP_RECTANGLE,
     36,                                /* default margin - points */
     {72.,72.},                 /* default dpi */
     NULL,                      /* knowncolors */
index 2ee484eb1d43a24dbb6807b2d889fc1ea2e74ffd..ce181889d85a1f8a85e8a5684f631ad181aaae2e 100644 (file)
@@ -262,10 +262,7 @@ static void vrml_begin_node(GVJ_t *job)
 
 static void vrml_end_node(GVJ_t *job)
 {
-    obj_state_t *obj = job->obj;
-    node_t *n = obj->n;
-
-    if (shapeOf(n) != SH_POINT) {
+    if (im) {
        gdImagePng(im, PNGfile);
        gdImageDestroy(im);
        im = NULL;
@@ -354,7 +351,6 @@ static void vrml_textpara(GVJ_t *job, pointf p, textpara_t * para)
        p.x -= para->width / 2;
        break;
     }
-/*     p.y += cstk[SP].fontsz*2/3; */
 
     mp = vrml_node_point(job, obj->n, p);
 
@@ -837,7 +833,7 @@ static gvrender_features_t vrml_features = {
     0,                          /* sizeof knowncolors */
     RGBA_BYTE,                  /* color_type */
     NULL,                       /* device */
-    NULL,                       /* gvloadimage target for usershapes */
+    "vrml",                     /* gvloadimage target for usershapes */
 };
 #endif                         /* HAVE_GD_PNG */
 #endif                         /* HAVE_LIBGD */