From: erg Date: Thu, 19 Aug 2010 20:11:49 +0000 (+0000) Subject: Redo code for using edge pos attributes to draw splines; X-Git-Tag: LAST_LIBGRAPH~32^2~1224 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bf7d2282a6837ba9ddcc9afe111451a644f70b23;p=graphviz Redo code for using edge pos attributes to draw splines; add -e flag to enable this. --- diff --git a/cmd/smyrna/main.c b/cmd/smyrna/main.c index 2e5de4813..f78e1d76d 100755 --- a/cmd/smyrna/main.c +++ b/cmd/smyrna/main.c @@ -91,6 +91,7 @@ char *smyrnaPath(char *suffix) static char *useString = "Usage: smyrns [-v?] \n\ -f - full-screen mode\n\ + -e - draw edges as splines if available\n\ -v - verbose\n\ -? - print usage\n"; @@ -105,8 +106,11 @@ static char *parseArgs(int argc, char *argv[], ViewInfo * view) { unsigned int c; - while ((c = getopt(argc, argv, ":Kf:txv?")) != -1) { + while ((c = getopt(argc, argv, ":eKf:txv?")) != -1) { switch (c) { + case 'e': + view->drawSplines = 1; + break; case 'v': SmyrnaVerbose = 1; break; diff --git a/cmd/smyrna/smyrnadefs.h b/cmd/smyrna/smyrnadefs.h index 9f71227b2..ae41cb989 100644 --- a/cmd/smyrna/smyrnadefs.h +++ b/cmd/smyrna/smyrnadefs.h @@ -704,6 +704,7 @@ typedef struct md5_byte_t final_key[16]; /*md5 result right before graph is saved */ char *initFileName; //file name from command line int initFile; + int drawSplines; colorschemaset *colschms; char *glade_file; char* temp; diff --git a/cmd/smyrna/topviewfuncs.c b/cmd/smyrna/topviewfuncs.c index dbdb74a73..03a75c30c 100644 --- a/cmd/smyrna/topviewfuncs.c +++ b/cmd/smyrna/topviewfuncs.c @@ -24,6 +24,8 @@ #include "xdot.h" #include "glutils.h" #include "selectionfuncs.h" +#include "memory.h" +#include static xdot *parseXdotwithattrs(void *e) { @@ -449,46 +451,182 @@ static void renderSelectedEdges(Agraph_t * g) } glEnd(); } -static int removeChar(char* str,char r) + +/* skipWS: + * Skip whitespace + */ +static char* skipWS (char* p) { - char* ptr=str; - int rv=0; - while (*ptr!='\0') - { - if(*ptr == r) - { - *ptr=' '; - rv++; + while (isspace(*p)) p++; + return p; +} + +/* skipNWS: + * Skip non-whitespace + */ +static char* skipNWS (char* p) +{ + while (*p && !isspace(*p)) p++; + return p; +} + +/* readPoint: + * Parse x,y[,z] and store in pt. + * If z is not specified, set to 0. + * Return pointer to next character after reading the point. + * Return NULL on error. + */ +static char* readPoint (char* p, xdot_point* pt) +{ + char* endp; + + pt->z = 0; + pt->x = strtod (p, &endp); + if (p == endp) { + return 0; + } + else + p = endp; + if (*p == ',') p++; + else return 0; + + pt->y = strtod (p, &endp); + if (p == endp) { + return 0; + } + else + p = endp; + if ((*p == ' ') || (*p == '\0')) return p; + else if (*p == ',') p++; + else return 0; + + pt->z = strtod (p, &endp); + if (p == endp) { + return 0; + } + else + return endp; +} + +/* countPoints: + * count number of points in pos attribute; store in cntp; + * check for e and s points; store if found and increment number of + * points by 3 for each. + * return start of point list (skip over e and s points). + * return NULL on failure + */ +static char* countPoints (char* pos, int* have_sp, xdot_point* sp, int* have_ep, xdot_point* ep, int* cntp) +{ + int cnt = 0; + char* p; + + pos = skipWS (pos); + if (*pos == 's') { + if ((pos = readPoint (pos+2, sp))) { + *have_sp = 1; + cnt += 3; } + else + return 0; + } + else + *have_sp = 0; - ptr++; + pos = skipWS (pos); + if (*pos == 'e') { + if ((pos = readPoint (pos+2, ep))) { + *have_ep = 1; + cnt += 3; + } + else + return 0; } - return rv; + else + *have_ep = 0; + + p = pos = skipWS (pos); + + while (*p) { + cnt++; + p = skipNWS (p); + p = skipWS (p); + } + *cntp = cnt; + + return pos; } -char* pos_to_xdot(char* xdots,char* buf) +/* storePoints: + * read comma-separated list of points + * and store them in ps + * Assumes enough storage is available. + * return -1 on error + */ +static int storePoints (char* pos, xdot_point* ps) { -/* -"e,227.75,177.25 186.27,218.73 196.2,208.8 209.32,195.68 220.44,184.56", -"B 4 186 219 196 209 209 196 220 185 ", _hdraw_="S 5 -solid c 9 -#000000ff C 9 -#000000ff P 3 223 187 228 177 218 182 ";*/ - char* pt; - int spaceCnt=0; - strcpy(buf,xdots); - pt=buf; - while ((spaceCnt == 0) && (*pt!='\0')) - { - if(*pt==' ') - spaceCnt++; - pt++; + + while (*pos) { + if ((pos = readPoint (pos, ps))) { + ps++; + pos = skipWS(pos); + } + else + return -1; } - return pt; + return 0; } +/* makeXDotSpline: + * Generate an xdot representation of an edge's pos attribute + */ +static xdot* makeXDotSpline (char* pos) +{ + xdot_point s, e; + int v, have_s, have_e, cnt; + int sz = sizeof(sdot_op); + xdot* xd; + xdot_op* op; + xdot_point* pts; + + if (*pos == '\0') return NULL; + + pos = countPoints (pos, &have_s, &s, &have_e, &e, &cnt); + if (pos == 0) return NULL; + + pts = N_NEW(cnt,xdot_point); + if (have_s) { + v = storePoints (pos, pts+3); + pts[0] = pts[1] = s; + pts[2] = pts[3]; + } + else + v = storePoints (pos, pts); + if (v) { + free (pts); + return NULL; + } + + if (have_e) { + pts[cnt-1] = pts[cnt-2] = e; + pts[cnt-3] = pts[cnt-4]; + } + + op = (xdot_op*)N_NEW(sz,char); + op->kind = xd_unfilled_bezier; + op->drawfunc = OpFns[xop_bezier]; + op->u.bezier.cnt = cnt; + op->u.bezier.pts = pts; + + xd = NEW(xdot); + xd->cnt = 1; + xd->sz = sz; + xd->ops = op; + + return xd; +} static void renderEdges(Agraph_t * g) { - char Buf[1024]; - char posBuf[1024]; Agedge_t *e; Agnode_t *v; Agsym_t* pos_attr = GN_pos(g); @@ -497,6 +635,7 @@ static void renderEdges(Agraph_t * g) glCompPoint posT; /*Tail position*/ glCompPoint posH; /*Head position*/ glCompColor c; + int drawSegs = !(pos_attr_e && view->drawSplines); /*xdots tend to be drawn as background shapes,that is why they are being rendered before edges*/ for (v = agfstnode(g); v; v = agnxtnode(g, v)) @@ -535,25 +674,19 @@ static void renderEdges(Agraph_t * g) if(ED_selected(e)) continue; glColor4f(c.R,c.G,c.B,1); - if(!pos_attr_e) - { + if (drawSegs) { posT=getPointFromStr(agxget(agtail(e), pos_attr)); posH=getPointFromStr(agxget(aghead(e), pos_attr)); draw_edge(&posT,&posH,getEdgeLength(e),0); ED_posTail(e) = posT; ED_posHead(e) = posH; } - else/*NOT IMPLEMENTED YET*/ - { - int pCount=0; - char* bf; - bf=pos_to_xdot(agxget(e,pos_attr_e),Buf); - pCount=removeChar(bf,','); - sprintf(posBuf,"B %d %s ",pCount,bf); - x=parseXDotFOn (posBuf, OpFns,sizeof(sdot_op), NULL); - draw_xdot(x,0); - if(x) + else { + x = makeXDotSpline (agxget(e,pos_attr_e)); + if (x) { + draw_xdot(x,0); freeXDot (x); + } } } }