static void initSubg (Agraph_t* sg, Agraph_t* g) { agbindrec(sg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE); GD_drawing(sg) = NEW(layout_t); GD_drawing(sg)->quantum = GD_drawing(g)->quantum; GD_drawing(sg)->dpi = GD_drawing(g)->dpi; GD_gvc(sg) = GD_gvc (g); GD_charset(sg) = GD_charset (g); GD_rankdir2(sg) = GD_rankdir2 (g); GD_nodesep(sg) = GD_nodesep(g); GD_ranksep(sg) = GD_ranksep(g); GD_fontnames(sg) = GD_fontnames(g); }
int initHTMLlexer(char *src, agxbuf * xb, htmlenv_t *env) { #ifdef HAVE_EXPAT state.xb = xb; agxbinit (&state.lb, SMALLBUF, NULL); state.ptr = src; state.mode = 0; state.warn = 0; state.error = 0; state.currtoklen = 0; state.prevtoklen = 0; state.inCell = 1; state.parser = XML_ParserCreate(charsetToStr(GD_charset(env->g))); XML_SetUserData(state.parser, GD_gvc(env->g)); XML_SetElementHandler(state.parser, (XML_StartElementHandler) startElement, endElement); XML_SetCharacterDataHandler(state.parser, characterData); return 0; #else static int first; if (!first) { agerr(AGWARN, "Not built with libexpat. Table formatting is not available.\n"); first++; } return 1; #endif }
/* make_label: * Assume str is freshly allocated for this instance, so it * can be freed in free_label. */ textlabel_t *make_label(void *obj, char *str, int kind, double fontsize, char *fontname, char *fontcolor) { textlabel_t *rv = NEW(textlabel_t); graph_t *g = NULL, *sg = NULL; node_t *n = NULL; edge_t *e = NULL; char *s; switch (agobjkind(obj)) { case AGRAPH: sg = (graph_t*)obj; g = sg->root; break; case AGNODE: n = (node_t*)obj; g = agroot(agraphof(n)); break; case AGEDGE: e = (edge_t*)obj; g = agroot(agraphof(aghead(e))); break; } rv->fontname = fontname; rv->fontcolor = fontcolor; rv->fontsize = fontsize; rv->charset = GD_charset(g); if (kind & LT_RECD) { rv->text = strdup(str); if (kind & LT_HTML) { rv->html = TRUE; } } else if (kind == LT_HTML) { rv->text = strdup(str); rv->html = TRUE; if (make_html_label(obj, rv)) { switch (agobjkind(obj)) { case AGRAPH: agerr(AGPREV, "in label of graph %s\n",agnameof(sg)); break; case AGNODE: agerr(AGPREV, "in label of node %s\n", agnameof(n)); break; case AGEDGE: agerr(AGPREV, "in label of edge %s %s %s\n", agnameof(agtail(e)), agisdirected(g)?"->":"--", agnameof(aghead(e))); break; } } } else { assert(kind == LT_NONE); /* This call just processes the graph object based escape sequences. The formatting escape * sequences (\n, \l, \r) are processed in make_simple_label. That call also replaces \\ with \. */ rv->text = strdup_and_subst_obj0(str, obj, 0); switch (rv->charset) { case CHAR_LATIN1: s = latin1ToUTF8(rv->text); break; default: /* UTF8 */ s = htmlEntityUTF8(rv->text, g); break; } free(rv->text); rv->text = s; make_simple_label(GD_gvc(g), rv); } return rv; }
/* do_graph_label: * If the ifdef'ed parts are added, clusters are guaranteed not * to overlap and have sufficient room for the label. The problem * is this approach does not use the actual size of the cluster, so * the resulting cluster tends to be far too large. */ void do_graph_label(graph_t* sg) { char *p, *pos, *just; int pos_ix; GVC_t *gvc = GD_gvc(sg->root); /* it would be nice to allow multiple graph labels in the future */ if ((p = agget(sg,"label"))) { char pos_flag; int html = aghtmlstr(p); GD_has_labels(sg->root) |= GRAPH_LABEL; GD_label(sg) = make_label(gvc, html,strdup_and_subst_graph(p,sg), late_double(sg,agfindattr(sg,"fontsize"),DEFAULT_FONTSIZE,MIN_FONTSIZE), late_nnstring(sg,agfindattr(sg,"fontname"),DEFAULT_FONTNAME), late_nnstring(sg,agfindattr(sg,"fontcolor"),DEFAULT_COLOR),sg); if (html) { if (make_html_label(gvc, GD_label(sg), sg)) agerr (AGPREV, "in label of graph %s\n", sg->name); } /* set label position */ pos = agget(sg,"labelloc"); if (sg != sg->root) { if (pos && (pos[0] == 'b')) pos_flag = LABEL_AT_BOTTOM; else pos_flag = LABEL_AT_TOP; } else { if (pos && (pos[0] == 't')) pos_flag = LABEL_AT_TOP; else pos_flag = LABEL_AT_BOTTOM; } just = agget(sg,"labeljust"); if (just) { if (just[0] == 'l') pos_flag |= LABEL_AT_LEFT; else if (just[0] == 'r') pos_flag |= LABEL_AT_RIGHT; } GD_label_pos(sg) = pos_flag; if(!GD_left_to_right(sg->root)) { point dpt; dpt = cvt2pt(GD_label(sg)->dimen); if (GD_label_pos(sg) & LABEL_AT_TOP) pos_ix = TOP_IX; else pos_ix = BOTTOM_IX; GD_border(sg)[pos_ix] = dpt; #if 0 if(g != g->root) { GD_border(g)[LEFT_IX].x = dpt.x/2; GD_border(g)[RIGHT_IX].x = dpt.x/2; GD_border(g)[LEFT_IX].y = 0; GD_border(g)[RIGHT_IX].y = 0; } #endif } else { point dpt; dpt = cvt2pt(GD_label(sg)->dimen); /* when rotated, the labels will be restored to TOP or BOTTOM */ if (GD_label_pos(sg) & LABEL_AT_TOP) pos_ix = RIGHT_IX; else pos_ix = LEFT_IX; GD_border(sg)[pos_ix].x = dpt.y; GD_border(sg)[pos_ix].y = dpt.x; #if 0 if(g != g->root) { GD_border(g)[TOP_IX].y = dpt.x/2; GD_border(g)[BOTTOM_IX].y = dpt.x/2; GD_border(g)[TOP_IX].x = 0; GD_border(g)[BOTTOM_IX].x = 0; } #endif } } }