/misc/src/release/graphviz-2.18-1/src/graphviz-2.18/plugin/core/gvrender_core_map.c

Go to the documentation of this file.
00001 /* $Id: gvrender_core_map.c,v 1.24 2007/10/03 19:00:06 ellson Exp $ $Revision: 1.24 $ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /**********************************************************
00005 *      This software is part of the graphviz package      *
00006 *                http://www.graphviz.org/                 *
00007 *                                                         *
00008 *            Copyright (c) 1994-2004 AT&T Corp.           *
00009 *                and is licensed under the                *
00010 *            Common Public License, Version 1.0           *
00011 *                      by AT&T Corp.                      *
00012 *                                                         *
00013 *        Information and Software Systems Research        *
00014 *              AT&T Research, Florham Park NJ             *
00015 **********************************************************/
00016 
00017 #ifdef HAVE_CONFIG_H
00018 #include "config.h"
00019 #endif
00020 
00021 #include "gvplugin_render.h"
00022 
00023 /* for g->name */
00024 #include "graph.h"
00025 
00026 extern char *xml_string(char *str);
00027 
00028 typedef enum { FORMAT_IMAP, FORMAT_ISMAP, FORMAT_CMAP, FORMAT_CMAPX, } format_type;
00029 
00030 static void map_output_shape (GVJ_t *job, map_shape_t map_shape, pointf * AF, int nump,
00031                 char* url, char *tooltip, char *target)
00032 {
00033     int i;
00034 
00035     static point *A;
00036     static int size_A;
00037 
00038     if (!AF || !nump)
00039         return;
00040 
00041     if (size_A < nump) {
00042         size_A = nump + 10;
00043         A = realloc(A, size_A * sizeof(point));
00044     }
00045     for (i = 0; i < nump; i++)
00046         PF2P(AF[i], A[i]);
00047 
00048     if (job->render.id == FORMAT_IMAP && url && url[0]) {
00049         switch (map_shape) {
00050         case MAP_RECTANGLE:
00051             /* Y_GOES_DOWN so need UL to LR */
00052             gvdevice_printf(job, "rect %s %d,%d %d,%d\n", url,
00053                 A[0].x, A[1].y, A[1].x, A[0].y);
00054             break;
00055         case MAP_CIRCLE:
00056             gvdevice_printf(job, "circle %s %d,%d,%d\n", url,
00057                 A[0].x, A[0].y, A[1].x-A[0].x);
00058             break;
00059         case MAP_POLYGON:
00060             gvdevice_printf(job, "poly %s", url);
00061             for (i = 0; i < nump; i++)
00062                 gvdevice_printf(job, " %d,%d", A[i].x, A[i].y);
00063             gvdevice_fputs(job, "\n");
00064             break;
00065         default:
00066             assert(0);
00067             break;
00068         }
00069 
00070     } else if (job->render.id == FORMAT_ISMAP && url && url[0]) {
00071         switch (map_shape) {
00072         case MAP_RECTANGLE:
00073             /* Y_GOES_DOWN so need UL to LR */
00074             gvdevice_printf(job, "rectangle (%d,%d) (%d,%d) %s %s\n",
00075                 A[0].x, A[1].y, A[1].x, A[0].y, url, tooltip);
00076             break;
00077         default:
00078             assert(0);
00079             break;
00080         }
00081 
00082     } else if (job->render.id == FORMAT_CMAP || job->render.id == FORMAT_CMAPX) {
00083         switch (map_shape) {
00084         case MAP_CIRCLE:
00085             gvdevice_fputs(job, "<area shape=\"circle\"");
00086             break;
00087         case MAP_RECTANGLE:
00088             gvdevice_fputs(job, "<area shape=\"rect\"");
00089             break;
00090         case MAP_POLYGON:
00091             gvdevice_fputs(job, "<area shape=\"poly\"");
00092             break;
00093         default:
00094             assert(0);
00095             break;
00096         }
00097         if (url && url[0]) {
00098             gvdevice_fputs(job, " href=\"");
00099             gvdevice_fputs(job, xml_string(url));
00100             gvdevice_fputs(job, "\"");
00101         }
00102         if (target && target[0]) {
00103             gvdevice_fputs(job, " target=\"");
00104             gvdevice_fputs(job, xml_string(target));
00105             gvdevice_fputs(job, "\"");
00106         }
00107         if (tooltip && tooltip[0]) {
00108             gvdevice_fputs(job, " title=\"");
00109             gvdevice_fputs(job, xml_string(tooltip));
00110             gvdevice_fputs(job, "\"");
00111         }
00112         /*
00113          * alt text is intended for the visually impaired, but such
00114          * folk are not likely to be clicking around on a graph anyway.
00115          * IE on the PC platform (but not on Macs) incorrectly
00116          * uses (non-empty) alt strings instead of title strings for tooltips.
00117          * To make tooltips work and avoid this IE issue,
00118          * while still satisfying usability guidelines
00119          * that require that there is always an alt string,
00120          * we generate just an empty alt string.
00121          */
00122         gvdevice_fputs(job, " alt=\"\"");
00123 
00124         gvdevice_fputs(job, " coords=\"");
00125         switch (map_shape) {
00126         case MAP_CIRCLE:
00127             gvdevice_printf(job, "%d,%d,%d", A[0].x, A[0].y, A[1].x-A[0].x);
00128             break;
00129         case MAP_RECTANGLE:
00130             /* Y_GOES_DOWN so need UL to LR */
00131             gvdevice_printf(job, "%d,%d,%d,%d", A[0].x, A[1].y, A[1].x, A[0].y);  
00132             break;
00133         case MAP_POLYGON:
00134             gvdevice_printf(job, "%d,%d", A[0].x, A[0].y);
00135             for (i = 1; i < nump; i++)
00136                 gvdevice_printf(job, " %d,%d", A[i].x, A[i].y);
00137             break;
00138         default:
00139             break;
00140         }
00141         if (job->render.id == FORMAT_CMAPX)
00142             gvdevice_fputs(job, "\"/>\n");
00143         else
00144             gvdevice_fputs(job, "\">\n");
00145     }
00146 }
00147 
00148 static void map_begin_page(GVJ_t * job)
00149 {
00150     obj_state_t *obj = job->obj;
00151     char *s;
00152 
00153     switch (job->render.id) {
00154     case FORMAT_IMAP:
00155         gvdevice_fputs(job, "base referer\n");
00156         if (obj->url && obj->url[0]) {
00157             gvdevice_fputs(job, "default ");
00158             gvdevice_fputs(job, xml_string(obj->url));
00159             gvdevice_fputs(job, "\n");
00160         }
00161         break;
00162     case FORMAT_ISMAP:
00163         if (obj->url && obj->url[0]) {
00164             gvdevice_fputs(job, "default ");
00165             gvdevice_fputs(job, xml_string(obj->url));
00166             gvdevice_fputs(job, " ");
00167             gvdevice_fputs(job, xml_string(obj->u.g->name));
00168             gvdevice_fputs(job, "\n");
00169         }
00170         break;
00171     case FORMAT_CMAPX:
00172         s = xml_string(obj->u.g->name);
00173         gvdevice_fputs(job, "<map id=\"");
00174         gvdevice_fputs(job, s);
00175         gvdevice_fputs(job, "\" name=\"");
00176         gvdevice_fputs(job, s);
00177         gvdevice_fputs(job, "\">\n");
00178         break;
00179     default:
00180         break;
00181     }
00182 }
00183 
00184 static void map_end_page(GVJ_t * job)
00185 {
00186     obj_state_t *obj = job->obj;
00187 
00188     switch (job->render.id) {
00189     case FORMAT_CMAP:
00190         map_output_shape(job, obj->url_map_shape, obj->url_map_p,obj->url_map_n,
00191                                     obj->url, obj->tooltip, obj->target);
00192         break;
00193     case FORMAT_CMAPX:
00194         map_output_shape(job, obj->url_map_shape, obj->url_map_p,obj->url_map_n,
00195                                     obj->url, obj->tooltip, obj->target);
00196         gvdevice_fputs(job, "</map>\n");
00197         break;
00198     default:
00199         break;
00200     }
00201 }
00202 
00203 #if 0
00204 static void map_begin_cluster(GVJ_t * job)
00205 {
00206     obj_state_t *obj = job->obj;
00207 
00208     gvdevice_printf(job, "%% %s\n", obj->u.sg->name);
00209 
00210     map_output_shape(job, obj->url_map_shape, obj->url_map_p, obj->url_map_n,
00211                 obj->url, obj->tooltip, obj->target);
00212 }
00213 
00214 static void map_begin_node(GVJ_t * job)
00215 {
00216     obj_state_t *obj = job->obj;
00217 
00218     map_output_shape(job, obj->url_map_shape, obj->url_map_p,obj->url_map_n,
00219                 obj->url, obj->tooltip, obj->target);
00220 }
00221 
00222 static void
00223 map_begin_edge(GVJ_t * job)
00224 {
00225     obj_state_t *obj = job->obj;
00226     int i, j = 0;
00227 
00228     map_output_shape(job, obj->url_map_shape, obj->url_map_p, obj->url_map_n,
00229                 obj->url, obj->tooltip, obj->target);
00230     map_output_shape(job, MAP_RECTANGLE, obj->tailurl_map_p, 2,
00231                 obj->tailurl, obj->tailtooltip, obj->tailtarget);
00232     map_output_shape(job, MAP_RECTANGLE, obj->headurl_map_p, 2,
00233                 obj->headurl, obj->headtooltip, obj->headtarget);
00234     map_output_shape(job, MAP_RECTANGLE, obj->tailendurl_map_p,2, 
00235                 obj->url, obj->tooltip, obj->target);
00236     map_output_shape(job, MAP_RECTANGLE, obj->headendurl_map_p, 2,
00237                 obj->url, obj->tooltip, obj->target);
00238     for (i = 0; i < obj->url_bsplinemap_poly_n; i++) {
00239         map_output_shape(job, MAP_POLYGON,
00240                 obj->url_bsplinemap_p+j, obj->url_bsplinemap_n[i],
00241                 obj->url, obj->tooltip, obj->target);
00242         j += obj->url_bsplinemap_n[i];
00243     }
00244 }
00245 #endif
00246 
00247 static void map_begin_anchor(GVJ_t * job, char *url, char *tooltip, char *target)
00248 {
00249     obj_state_t *obj = job->obj;
00250 
00251     map_output_shape(job, obj->url_map_shape, obj->url_map_p, obj->url_map_n, 
00252                 url, tooltip, target);
00253 }
00254 
00255 static gvrender_engine_t map_engine = {
00256     0,                          /* map_begin_job */
00257     0,                          /* map_end_job */
00258     0,                          /* map_begin_graph */
00259     0,                          /* map_end_graph */
00260     0,                          /* map_begin_layer */
00261     0,                          /* map_end_layer */
00262     map_begin_page,
00263     map_end_page,
00264     0,                          /* map_begin_cluster */
00265     0,                          /* map_end_cluster */
00266     0,                          /* map_begin_nodes */
00267     0,                          /* map_end_nodes */
00268     0,                          /* map_begin_edges */
00269     0,                          /* map_end_edges */
00270     0,                          /* map_begin_node */
00271     0,                          /* map_end_node */
00272     0,                          /* map_begin_edge */
00273     0,                          /* map_end_edge */
00274     map_begin_anchor,
00275     0,                          /* map_end_anchor */
00276     0,                          /* map_textpara */
00277     0,                          /* map_resolve_color */
00278     0,                          /* map_ellipse */
00279     0,                          /* map_polygon */
00280     0,                          /* map_bezier */
00281     0,                          /* map_polyline */
00282     0,                          /* map_comment */
00283     0,                          /* map_library_shape */
00284 };
00285 
00286 static gvrender_features_t render_features_map = {
00287     EMIT_CLUSTERS_LAST
00288         | GVRENDER_Y_GOES_DOWN
00289         | GVRENDER_DOES_MAPS
00290         | GVRENDER_DOES_LABELS
00291         | GVRENDER_DOES_TOOLTIPS
00292         | GVRENDER_DOES_TARGETS
00293         | GVRENDER_DOES_MAP_RECTANGLE, /* flags */
00294     4.,                         /* default pad - graph units */
00295     NULL,                       /* knowncolors */
00296     0,                          /* sizeof knowncolors */
00297     0,                          /* color_type */
00298 };
00299 
00300 static gvdevice_features_t device_features_map = {
00301     GVRENDER_DOES_MAP_CIRCLE
00302         | GVRENDER_DOES_MAP_POLYGON, /* flags */
00303     {0.,0.},                    /* default margin - points */
00304     {0.,0.},                    /* default page width, height - points */
00305     {96.,96.},                  /* default dpi */
00306 };
00307 
00308 static gvdevice_features_t device_features_map_nopoly = {
00309     0,                          /* flags */
00310     {0.,0.},                    /* default margin - points */
00311     {0.,0.},                    /* default page width, height - points */
00312     {96.,96.},                  /* default dpi */
00313 };
00314 
00315 gvplugin_installed_t gvrender_map_types[] = {
00316     {FORMAT_ISMAP, "map", 1, &map_engine, &render_features_map},
00317     {0, NULL, 0, NULL, NULL}
00318 };
00319 
00320 gvplugin_installed_t gvdevice_map_types[] = {
00321     {FORMAT_ISMAP, "ismap:map", 1, NULL, &device_features_map_nopoly},
00322     {FORMAT_CMAP, "cmap:map", 1, NULL, &device_features_map},
00323     {FORMAT_IMAP, "imap:map", 1, NULL, &device_features_map},
00324     {FORMAT_CMAPX, "cmapx:map", 1, NULL, &device_features_map},
00325     {FORMAT_IMAP, "imap_np:map", 1, NULL, &device_features_map_nopoly},
00326     {FORMAT_CMAPX, "cmapx_np:map", 1, NULL, &device_features_map_nopoly},
00327     {0, NULL, 0, NULL, NULL}
00328 };

Generated on Mon Mar 31 19:03:28 2008 for Graphviz by  doxygen 1.5.1