/* This software may only be used by you under license from AT&T Corp. ("AT&T"). A copy of AT&T's Source Code Agreement is available at AT&T's Internet website having the URL: If you received this software without first entering into a license with AT&T, you have an infringing copy of this software and cannot use it without violating AT&T's intellectual property rights. */ #pragma prototyped #include "render.h" #include "gd.h" /* IMAP font modifiers */ #define REGULAR 0 #define BOLD 1 #define ITALIC 2 /* IMAP 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 */ #define SCALE (GD_RESOLUTION/72.0) /* IMAP bold line constant */ #define WIDTH_NORMAL 1 #define WIDTH_BOLD 3 /* static int N_pages; */ /* static point Pages; */ static double ArgScale; static double Scale; static int Rot; static int onetime = TRUE; typedef struct context_t { char color_ix, *fontfam, fontopt, font_was_set; char pen, fill, penwidth, style_was_set; double fontsz; } context_t; #define MAXNEST 4 static context_t cstk[MAXNEST]; static int SP; void map_output_rect (pointf p1, pointf p2, char *url, char *label, char *tooltip) { pointf pp1,pp2; double t; if (!(url && url[0])) return; /* apply scaling and translation if necessary */ if (Output_lang == IMAP || Output_lang == ISMAP || Output_lang == CMAP) { pp1 = gdpt(p1); pp2 = gdpt(p2); } else { pp1 = p1; pp2 = p2; } /* fix up coordinate order */ if (pp2.x < pp1.x) { t = pp2.x; pp2.x = pp1.x; pp1.x = t; } if (pp2.y < pp1.y) { t = pp2.y; pp2.y = pp1.y; pp1.y = t; } if (Output_lang == IMAP) { fprintf(Output_file,"rect %s %d,%d %d,%d\n", url, ROUND(pp1.x),ROUND(pp1.y),ROUND(pp2.x),ROUND(pp2.y)); } else if (Output_lang == ISMAP) { fprintf(Output_file,"rectangle (%d,%d) (%d,%d) %s %s\n", ROUND(pp1.x),ROUND(pp1.y),ROUND(pp2.x),ROUND(pp2.y), url,label); } else if (Output_lang == CMAP) { fprintf(Output_file,"\"%s\"",\n", ROUND(pp1.x),ROUND(pp1.y),ROUND(pp2.x),ROUND(pp2.y)); } else if (Output_lang == POSTSCRIPT || Output_lang == PDF) { fprintf(Output_file,"[ /Rect [ %d %d %d %d ]\n" " /Border [ 0 0 0 ]\n" " /Action << /Subtype /URI /URI %s >>\n" " /Subtype /Link\n" "/ANN pdfmark\n", ROUND(pp1.x),ROUND(pp1.y),ROUND(pp2.x),ROUND(pp2.y), ps_string(url)); } } /* radius of mouse-sensitive region around a point */ #define FUZZ 3 void map_output_fuzzy_point (pointf p, char *url, char *label, char *tooltip) { pointf p1, p2; p1.x = p.x - FUZZ; p1.y = p.y - FUZZ; p2.x = p.x + FUZZ; p2.y = p.y + FUZZ; map_output_rect(p1, p2, url, label, tooltip); } static void map_reset(void) { onetime = TRUE; } static void init_imap(void) { SP = 0; cstk[0].color_ix = 0; /* IMAP color index 0-7 */ 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 sold */ cstk[0].fill = P_NONE; cstk[0].penwidth = WIDTH_NORMAL; } static void map_font(context_t* cp) { } static void map_color(int i) { } static void map_style(context_t* cp) { } static void map_begin_job(FILE *ofp, graph_t *g, char **lib, char *user, char *info[], point pages) { /* Pages = pages; */ /* N_pages = pages.x * pages.y; */ if (Output_lang == IMAP) { fprintf(Output_file,"base referer\n"); } else if (Output_lang == ISMAP) { /* fprintf(Output_file,"base referer\n"); */ } else if (Output_lang == CMAP) { /* fprintf(Output_file,"base referer\n"); */ } else if (Output_lang == POSTSCRIPT || Output_lang == PDF) { /* fprintf(Output_file,"base referer\n"); */ } } static void map_end_job(void) { } static void map_begin_graph(graph_t* g, box bb, point pb) { gd_begin_graph(g, bb, pb); if (onetime) { init_imap(); onetime = FALSE; } } static pointf Default_p1,Default_p2; static char *Default_URL, *Default_label; static void map_begin_page(graph_t *g, point page, double scale, int rot, point offset) { char *s; ArgScale = scale; Scale = scale * SCALE; Rot = rot; gd_begin_page(g, page, scale, rot, offset); Default_URL = NULL; if ((s = agget(g, "URL")) && strlen(s)) { if (Output_lang == IMAP) { fprintf(Output_file,"default %s\n",s); } else if (Output_lang == ISMAP) { fprintf(Output_file,"default %s %s\n",s,g->name); } else if (Output_lang == CMAP) { Default_URL = strdup_and_subst_graph(s,g); Default_label = g->name; Default_p1.x = GD_bb(g).LL.x; Default_p1.y = GD_bb(g).LL.y; Default_p2.x = GD_bb(g).UR.x; Default_p2.y = GD_bb(g).UR.y; } } } static void map_end_page(void) { if (Default_URL) { map_output_rect(Default_p1,Default_p2,Default_URL,Default_label,""); free(Default_URL); } } static void map_end_graph(void) { } void map_begin_cluster(graph_t* g) { char *s, *t=""; pointf p1,p2; if ((s = agget(g, "URL")) && strlen(s)) { if (GD_label(g) != NULL) t=GD_label(g)->text; p1.x = GD_bb(g).LL.x; p1.y = GD_bb(g).LL.y; p2.x = GD_bb(g).UR.x; p2.y = GD_bb(g).UR.y; s = strdup_and_subst_graph(s,g); map_output_rect(p1,p2,s,t,t); free(s); } } static void map_end_cluster(void) { } static void map_begin_nodes(void) { } static void map_end_nodes(void) { } static void map_begin_edges(void) { } static void map_end_edges(void) { } void map_begin_node(node_t* n) { char *url=NULL, *tooltip=NULL; char *m_tooltip=NULL; pointf p1,p2; if ((url = agget(n, "URL")) && url[0]) { p1.x = ND_coord_i(n).x - ND_lw_i(n); p1.y = ND_coord_i(n).y - (ND_ht_i(n)/2); p2.x = ND_coord_i(n).x + ND_rw_i(n); p2.y = ND_coord_i(n).y + (ND_ht_i(n)/2); url = strdup_and_subst_node(url,n); if ((tooltip = agget(n, "tooltip")) && tooltip[0]) { m_tooltip = tooltip = strdup_and_subst_node(tooltip,n); } else { tooltip = ND_label(n)->text; } map_output_rect(p1,p2,url,ND_label(n)->text,tooltip); if (m_tooltip) free(m_tooltip); free(url); } } static void map_end_node(void) { } void map_begin_edge(edge_t* e) { /* strings */ char *label=NULL, *taillabel=NULL, *headlabel=NULL; char *url=NULL, *headurl=NULL, *tailurl=NULL; char *tooltip=NULL, *tailtooltip=NULL, *headtooltip=NULL; /* malloc flags for strings */ char *m_url=NULL, *m_headurl=NULL, *m_tailurl=NULL; char *m_tooltip=NULL, *m_tailtooltip=NULL, *m_headtooltip=NULL; textlabel_t *lab=NULL, *tlab=NULL, *hlab=NULL; pointf p,p1,p2; bezier bz; /* establish correct text for main edge label, URL, tooltip */ if ((lab=ED_label(e))) { label = lab->text; } else { label = ""; } if ((url = agget(e, "URL")) && url[0]) { m_url = url = strdup_and_subst_edge(url,e); if ((tooltip = agget(e, "tooltip")) && tooltip[0]) { m_tooltip = tooltip = strdup_and_subst_edge(tooltip,e); } else { tooltip = label; } } else { tooltip = ""; } /* establish correct text for tail label, URL, tooltip */ if ((tlab=ED_tail_label(e))) { taillabel = tlab->text; } else { taillabel=label; } if ((tailurl = agget(e, "tailURL")) && tailurl[0]) { m_tailurl = tailurl = strdup_and_subst_edge(tailurl,e); if ((tailtooltip = agget(e, "tailtooltip")) && tailtooltip[0]) { m_tailtooltip = tailtooltip = strdup_and_subst_edge(tailtooltip,e); } else { tailtooltip = taillabel; } } else if (url) { tailurl = url; tailtooltip = tooltip; } /* establish correct text for head label, URL, tooltip */ if ((hlab=ED_head_label(e))) { headlabel = hlab->text; } else { headlabel = label; } if ((headurl = agget(e, "headURL")) && headurl[0]) { m_headurl = headurl = strdup_and_subst_edge(headurl,e); if ((headtooltip = agget(e, "headtooltip")) && headtooltip[0]) { m_headtooltip = headtooltip = strdup_and_subst_edge(headtooltip,e); } else { headtooltip = headlabel; } } else if (url) { headurl = url; headtooltip = tooltip; } /* strings are now set - next we map the three labels */ if (lab && url) { /* map a rectangle around the edge label */ p1.x = lab->p.x - lab->dimen.x*64/2; p1.y = lab->p.y - lab->dimen.y*64/2; p2.x = lab->p.x + lab->dimen.x*64/2; p2.y = lab->p.y + lab->dimen.y*64/2; map_output_rect(p1,p2,url,label,tooltip); } if (tlab && (url || tailurl)) { /* map a rectangle around the edge taillabel */ p1.x = tlab->p.x - tlab->dimen.x*64/2; p1.y = tlab->p.y - tlab->dimen.y*64/2; p2.x = tlab->p.x + tlab->dimen.x*64/2; p2.y = tlab->p.y + tlab->dimen.y*64/2; map_output_rect(p1,p2,tailurl,taillabel,tailtooltip); } if (hlab && (url || headurl)) { /* map a rectangle around the edge headlabel */ p1.x = hlab->p.x - hlab->dimen.x*64/2; p1.y = hlab->p.y - hlab->dimen.y*64/2; p2.x = hlab->p.x + hlab->dimen.x*64/2; p2.y = hlab->p.y + hlab->dimen.y*64/2; map_output_rect(p1,p2,headurl,headlabel,headtooltip); } #if 0 # FIXME - what is this supposed to do? Perhaps map spline control points? if (ED_spl(e) && url) { int i,j; for (i = 0; i < ED_spl(e)->size; i++) { bz = ED_spl(e)->list[i]; for (j = 0; j < bz.size; j +=3) { if (((i == 0) && (j == 0)) /* origin */ || ((i == (ED_spl(e)->size -1)) && (j == (bz.size - 1)))) { continue; } p.x = bz.list[j].x; p.y = bz.list[j].y; map_output_fuzzy_point(p, url, ED_label(e)->text); } } } #endif /* finally we map the two ends of the edge where they touch nodes */ /* process intersecion with tail node */ if (ED_spl(e) && (url || tailurl)) { bz = ED_spl(e)->list[0]; if (bz.sflag) { /* Arrow at start of splines */ p.x = bz.sp.x; p.y = bz.sp.y; } else { /* No arrow at start of splines */ p.x = bz.list[0].x; p.y = bz.list[0].y; } map_output_fuzzy_point(p, tailurl, taillabel, tailtooltip); } /* process intersection with head node */ if (ED_spl(e) && (url || headurl)) { bz = ED_spl(e)->list[ED_spl(e)->size-1]; if (bz.eflag) { /* Arrow at end of splines */ p.x = bz.ep.x; p.y = bz.ep.y; } else { /* No arrow at end of splines */ p.x = bz.list[bz.size-1].x; p.y = bz.list[bz.size-1].y; } map_output_fuzzy_point(p, headurl, headlabel, headtooltip); } if (m_url) free(m_url); if (m_tailurl) free(m_tailurl); if (m_headurl) free(m_headurl); if (m_tooltip) free(m_tooltip); if (m_tailtooltip) free(m_tailtooltip); if (m_headtooltip) free(m_headtooltip); } static void map_end_edge(void) { } static void map_begin_context(void) { assert(SP + 1 < MAXNEST); cstk[SP + 1] = cstk[SP]; SP++; } static void map_end_context(void) { int c, psp = SP - 1; assert(SP > 0); if (cstk[SP].color_ix != (c = cstk[psp].color_ix)) map_color(c); if (cstk[SP].font_was_set) map_font(&(cstk[psp])); if (cstk[SP].style_was_set) map_style(&(cstk[psp])); /* free(cstk[psp].fontfam); */ SP = psp; } static void map_set_font(char* name, double size) { } static void map_set_color(char* name) { } static void map_set_style(char** s) { } static void map_textline(point p, textline_t *line) { } static void map_bezier(point* A, int n, int arrow_at_start, int arrow_at_end) { } static void map_polygon(point *A, int n, int filled) { } static void map_ellipse(point p, int rx, int ry, int filled) { } static void map_polyline(point* A, int n) { } static void map_user_shape(char *name, point *A,int n, int filled) { } codegen_t IMAP_CodeGen = { map_reset, map_begin_job, map_end_job, map_begin_graph, map_end_graph, map_begin_page, map_end_page, map_begin_cluster, map_end_cluster, map_begin_nodes, map_end_nodes, map_begin_edges, map_end_edges, map_begin_node, map_end_node, map_begin_edge, map_end_edge, map_begin_context, map_end_context, map_set_font, map_textline, map_set_color, map_set_color, map_set_style, map_ellipse, map_polygon, map_bezier, map_polyline, 0 /* map_arrowhead */, map_user_shape, 0 /* map_comment */, gd_textsize }; codegen_t ISMAP_CodeGen = { map_reset, map_begin_job, map_end_job, map_begin_graph, map_end_graph, map_begin_page, map_end_page, map_begin_cluster, map_end_cluster, map_begin_nodes, map_end_nodes, map_begin_edges, map_end_edges, map_begin_node, map_end_node, map_begin_edge, map_end_edge, map_begin_context, map_end_context, map_set_font, map_textline, map_set_color, map_set_color, map_set_style, map_ellipse, map_polygon, map_bezier, map_polyline, 0 /* map_arrowhead */, map_user_shape, 0 /* map_comment */, gd_textsize }; codegen_t CMAP_CodeGen = { map_reset, map_begin_job, map_end_job, map_begin_graph, map_end_graph, map_begin_page, map_end_page, map_begin_cluster, map_end_cluster, map_begin_nodes, map_end_nodes, map_begin_edges, map_end_edges, map_begin_node, map_end_node, map_begin_edge, map_end_edge, map_begin_context, map_end_context, map_set_font, map_textline, map_set_color, map_set_color, map_set_style, map_ellipse, map_polygon, map_bezier, map_polyline, 0 /* map_arrowhead */, map_user_shape, 0 /* map_comment */, gd_textsize };