00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef HAVE_CONFIG_H
00018 #include "config.h"
00019 #endif
00020
00021 #include "gvplugin_render.h"
00022
00023
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
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
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
00114
00115
00116
00117
00118
00119
00120
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
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,
00257 0,
00258 0,
00259 0,
00260 0,
00261 0,
00262 map_begin_page,
00263 map_end_page,
00264 0,
00265 0,
00266 0,
00267 0,
00268 0,
00269 0,
00270 0,
00271 0,
00272 0,
00273 0,
00274 map_begin_anchor,
00275 0,
00276 0,
00277 0,
00278 0,
00279 0,
00280 0,
00281 0,
00282 0,
00283 0,
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,
00294 4.,
00295 NULL,
00296 0,
00297 0,
00298 };
00299
00300 static gvdevice_features_t device_features_map = {
00301 GVRENDER_DOES_MAP_CIRCLE
00302 | GVRENDER_DOES_MAP_POLYGON,
00303 {0.,0.},
00304 {0.,0.},
00305 {96.,96.},
00306 };
00307
00308 static gvdevice_features_t device_features_map_nopoly = {
00309 0,
00310 {0.,0.},
00311 {0.,0.},
00312 {96.,96.},
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 };