From: ellson Date: Wed, 23 Jan 2008 20:52:43 +0000 (+0000) Subject: Add smyrna to main graphviz tree X-Git-Tag: LAST_LIBGRAPH~32^2~4833 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b258c5e17a491a2794267c57a2f7b010106eaecd;p=graphviz Add smyrna to main graphviz tree --- diff --git a/lib/xdot/Makefile.am b/lib/xdot/Makefile.am new file mode 100644 index 000000000..974603e04 --- /dev/null +++ b/lib/xdot/Makefile.am @@ -0,0 +1,17 @@ +# $Id$ $Revision$ +# ## Process this file with automake to produce Makefile.in + +AM_CPPFLAGS = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/lib/cgraph \ + -I$(top_srcdir)/lib/cdt \ + -I$(top_srcdir)/lib/utilities \ + -I$(top_srcdir)/cmd/smyrna \ + $(GTK_CFLAGS) $(GTKGL_CFLAGS) $(GTKGLEXT_CFLAGS) $(GLADE_CFLAGS) $(FREETYPE2_CFLAGS) + +if WITH_SMYRNA +noinst_HEADERS = xdot.h +noinst_LTLIBRARIES = libxdot_C.la +endif + +libxdot_C_la_SOURCES = xdot.c diff --git a/lib/xdot/xdot.c b/lib/xdot/xdot.c new file mode 100755 index 000000000..6c766d298 --- /dev/null +++ b/lib/xdot/xdot.c @@ -0,0 +1,811 @@ +/* vim:set shiftwidth=4 ts=8: */ + +/********************************************************** +* This software is part of the graphviz package * +* http://www.graphviz.org/ * +* * +* Copyright (c) 1994-2007 AT&T Corp. * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Corp. * +* * +* Information and Software Systems Research * +* AT&T Research, Florham Park NJ * +**********************************************************/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define NEW(t) (t*)malloc(sizeof(t)) +#define N_NEW(n,t) (t*)malloc((n)*sizeof(t)) +#define RALLOC(size,ptr,type) ((type*)realloc(ptr,(size)*sizeof(type))) + +static char* +parseFloat (char* s, float* fp) +{ + int r, sz; + r = sscanf(s, "%f%n", fp, &sz); + assert (r == 1); + return (s+sz); +} + +static char* +parseInt (char* s, int* ip) +{ + int r, sz; + r = sscanf(s, "%d%n", ip, &sz); + assert (r == 1); + return (s+sz); +} + +static char* +parsePoint (char* s, xdot_point* pp) +{ + int r, sz; + r = sscanf(s, "%d %d%n", &(pp->x), &(pp->y), &sz); + assert (r == 2); + pp->z = 0; + return (s+sz); +} + +static char* +parseRect (char* s, xdot_rect* rp) +{ + int r, sz; + r = sscanf(s, "%d %d %d %d%n", &(rp->x), &(rp->y), &(rp->w), &(rp->h), &sz); + assert (r == 4); + return (s+sz); +} + +static char* +parsePolyline (char* s, xdot_polyline* pp) +{ + int i; + xdot_point* pts; + + s = parseInt (s, &i); + pts = N_NEW(i, xdot_point); + pp->cnt = i; + for (i = 0; i < pp->cnt; i++) + s = parsePoint (s, pts+i); + pp->pts = pts; + return s; +} + +static char* +parseString (char* s, char** sp) +{ + int i; + char* c; + s = parseInt (s, &i); + c = N_NEW(i+1, char); + while (*s++ != '-'); + memcpy (c, s, i); + c[i] = '\0'; + *sp = c; + return (s+i); +} + +static char* +parseAlign (char* s, xdot_align* ap) +{ + int i; + s = parseInt (s, &i); + if (i < 0) *ap = xd_left; + else if (i > 0) *ap = xd_right; + else *ap = xd_center; + return s; +} + +static char* +parseOp (xdot_op* op, char* s) +{ + while (isspace(*s)) s++; + switch (*s++) { + case 'E' : + op->kind = xd_filled_ellipse; + s = parseRect (s, &op->u.ellipse); + op->drawfunc=DrawEllipse; + break; + + case 'e' : + op->kind = xd_unfilled_ellipse; + s = parseRect (s, &op->u.ellipse); + op->drawfunc=DrawEllipse; + break; + + case 'P' : + op->kind = xd_filled_polygon; + s = parsePolyline (s, &op->u.polygon); + op->drawfunc=DrawPolygon; + break; + + case 'p' : + op->kind = xd_unfilled_polygon; + s = parsePolyline (s, &op->u.polygon); + op->drawfunc=DrawPolygon; + break; + + case 'b' : + op->kind = xd_filled_bezier; + s = parsePolyline (s, &op->u.bezier); + op->drawfunc=DrawBeziers; + break; + + case 'B' : + op->kind = xd_unfilled_bezier; + s = parsePolyline (s, &op->u.bezier); + op->drawfunc=DrawBeziers; + break; + + case 'c' : + op->kind = xd_pen_color; + s = parseString (s, &op->u.color); + op->drawfunc=SetPenColor; + break; + + case 'C' : + op->kind = xd_fill_color; + s = parseString (s, &op->u.color); + op->drawfunc=SetFillColor; + break; + + case 'L' : + op->kind = xd_polyline; + s = parsePolyline (s, &op->u.polyline); + op->drawfunc=DrawPolyline; + break; + + case 'T' : + op->kind = xd_text; + s = parseInt (s, &op->u.text.x); + s = parseInt (s, &op->u.text.y); + s = parseAlign (s, &op->u.text.align); + s = parseInt (s, &op->u.text.width); + s = parseString (s, &op->u.text.text); + op->u.text.texture=NULL; + op->drawfunc=EmbedText; + break; + + case 'F' : + op->kind = xd_font; + s = parseFloat (s, &op->u.font.size); + s = parseString (s, &op->u.font.name); + op->drawfunc=SetFont; + break; + + case 'S' : + op->kind = xd_style; + s = parseString (s, &op->u.style); + op->drawfunc=SetStyle; + break; + + case 'I' : + op->kind = xd_image; + s = parseRect (s, &op->u.image.pos); + s = parseString (s, &op->u.image.name); + op->drawfunc=InsertImage; + break; + + default : + s = 0; + break; + } + return s; +} + +#define XDBSIZE 100 + +xdot* +parseXDot (char* s) +{ + xdot* x; + xdot_op op; + xdot_op* ops; + int bufsz = XDBSIZE; + if (!s) + return NULL; + x = NEW(xdot); + ops = N_NEW(XDBSIZE, xdot_op); + + x->cnt = 0; + while ((s = parseOp (&op, s))) { + if (x->cnt == bufsz) { + bufsz += XDBSIZE; + ops = RALLOC (bufsz, ops, xdot_op); + } + ops[x->cnt] = op; + x->cnt++; + } + if (x->cnt) + x->ops = RALLOC (x->cnt, ops, xdot_op); + else { + free (x); + x = 0; + } + return x; +} + +typedef void (*pf)(char*, void*); + +static void +printRect (xdot_rect* r, pf print, void* info) +{ + char buf[128]; + + sprintf (buf, " %d %d %d %d", r->x, r->y, r->w, r->h); + print (buf, info); +} + +static void +printPolyline (xdot_polyline* p, pf print, void* info) +{ + int i; + char buf[64]; + + sprintf (buf, " %d", p->cnt); + print (buf, info); + for (i = 0; i< p->cnt; i++) { + sprintf (buf, " %d %d", p->pts[i].x, p->pts[i].y); + print (buf, info); + } +} + +static void +printString (char* p, pf print, void* info) +{ + char buf[30]; + + sprintf (buf, " %d -", strlen(p)); + print (buf, info); + print (p, info); +} + +static void +printInt (int i, pf print, void* info) +{ + char buf[30]; + + sprintf (buf, " %d", i); + print (buf, info); +} + +static void +printFloat (float f, pf print, void* info) +{ + char buf[128]; + + sprintf (buf, " %f", f); + print (buf, info); +} + +static void +printAlign (xdot_align a, pf print, void* info) +{ + switch (a) { + case xd_left : + print (" -1", info); + break; + case xd_right : + print (" 1", info); + break; + case xd_center : + print (" 0", info); + break; + } +} + +static void +printXDot_Op (xdot_op* op, pf print, void* info) +{ + switch (op->kind) { + case xd_filled_ellipse : + print ("E", info); + printRect (&op->u.ellipse, print, info); + break; + case xd_unfilled_ellipse : + print ("e", info); + printRect (&op->u.ellipse, print, info); + break; + case xd_filled_polygon : + print ("P", info); + printPolyline (&op->u.polygon, print, info); + break; + case xd_unfilled_polygon : + print ("p", info); + printPolyline (&op->u.polygon, print, info); + break; + case xd_filled_bezier : + print ("b", info); + op->kind = xd_filled_bezier; + printPolyline (&op->u.bezier, print, info); + break; + case xd_unfilled_bezier : + print ("B", info); + printPolyline (&op->u.bezier, print, info); + break; + case xd_pen_color : + print ("c", info); + printString (op->u.color, print, info); + break; + case xd_fill_color : + print ("C", info); + printString (op->u.color, print, info); + break; + case xd_polyline : + print ("L", info); + printPolyline (&op->u.polyline, print, info); + break; + case xd_text : + print ("T", info); + printInt (op->u.text.x, print, info); + printInt (op->u.text.y, print, info); + printAlign (op->u.text.align, print, info); + printInt (op->u.text.width, print, info); + printString (op->u.text.text, print, info); + break; + case xd_font : + print ("F", info); + op->kind = xd_font; + printFloat (op->u.font.size, print, info); + printString (op->u.font.name, print, info); + break; + case xd_style : + print ("S", info); + printString (op->u.style, print, info); + break; + case xd_image : + print ("I", info); + printRect (&op->u.image.pos, print, info); + printString (op->u.image.name, print, info); + break; + } +} + +_printXDot (xdot* x, pf print, void* info) +{ + int i; + for (i = 0; i < x->cnt; i++) { + printXDot_Op (x->ops+i, print, info); + if (i < x->cnt-1) print (" ", info); + } +} + +typedef struct { + unsigned char *buf; /* start of buffer */ + unsigned char *ptr; /* next place to write */ + unsigned char *eptr; /* end of buffer */ + int dyna; /* true if buffer is malloc'ed */ +} agxbuf; + +#define agxbputc(X,C) ((((X)->ptr >= (X)->eptr) ? agxbmore(X,1) : 0), \ + (int)(*(X)->ptr++ = ((unsigned char)C))) +#define agxbuse(X) (agxbputc(X,'\0'),(char*)((X)->ptr = (X)->buf)) + +static void +agxbinit(agxbuf * xb, unsigned int hint, unsigned char *init) +{ + if (init) { + xb->buf = init; + xb->dyna = 0; + } else { + if (hint == 0) + hint = BUFSIZ; + xb->dyna = 1; + xb->buf = N_NEW(hint, unsigned char); + } + xb->eptr = xb->buf + hint; + xb->ptr = xb->buf; + *xb->ptr = '\0'; +} +static int +agxbmore(agxbuf * xb, unsigned int ssz) +{ + int cnt; /* current no. of characters in buffer */ + int size; /* current buffer size */ + int nsize; /* new buffer size */ + unsigned char *nbuf; /* new buffer */ + + size = xb->eptr - xb->buf; + nsize = 2 * size; + if (size + ssz > nsize) + nsize = size + ssz; + cnt = xb->ptr - xb->buf; + if (xb->dyna) { + nbuf = realloc(xb->buf, nsize); + } else { + nbuf = N_NEW(nsize, unsigned char); + memcpy(nbuf, xb->buf, cnt); + xb->dyna = 1; + } + xb->buf = nbuf; + xb->ptr = xb->buf + cnt; + xb->eptr = xb->buf + nsize; + return 0; +} + +static int +agxbput(char* s, agxbuf * xb) +{ + unsigned int ssz = strlen (s); + if (xb->ptr + ssz > xb->eptr) + agxbmore(xb, ssz); + memcpy(xb->ptr, s, ssz); + xb->ptr += ssz; + return ssz; +} + +/* agxbfree: + * Free any malloced resources. + */ +static void +agxbfree(agxbuf * xb) +{ + if (xb->dyna) + free(xb->buf); +} + +char* +sprintXDot (xdot* x) +{ + char* s; + unsigned char buf[BUFSIZ]; + agxbuf xb; + agxbinit (&xb, BUFSIZ, buf); + _printXDot (x, (pf)agxbput, &xb); + s = strdup(agxbuse (&xb)); + agxbfree (&xb); + + return s; +} + +void +fprintXDot (FILE* fp, xdot* x) +{ + _printXDot (x, (pf)fputs, fp); +} + +static void +freeXOpData (xdot_op* x) +{ + switch (x->kind) { + case xd_filled_polygon : + case xd_unfilled_polygon : + free (x->u.polyline.pts); + break; + case xd_filled_bezier : + case xd_unfilled_bezier : + free (x->u.polyline.pts); + break; + case xd_polyline : + free (x->u.polyline.pts); + break; + case xd_text : + free (x->u.text.text); + break; + case xd_fill_color : + case xd_pen_color : + free (x->u.color); + break; + case xd_font : + free (x->u.font.name); + break; + case xd_style : + free (x->u.style); + break; + case xd_image : + free (x->u.image.name); + break; + } +} + +void +freeXDot (xdot* x) +{ + int i; + for (i = 0; i < x->cnt; i++) freeXOpData (x->ops+i); + free (x->ops); + free (x); +} + +extern char* move_xdot(void* obj,xdot* x,int dx,int dy,int dz) +{ + int i=0; + int j=0; + int a=0; + char* pch; + int pos[100]; //maximum pos count hopefully does not exceed 100 + if (!x) + return "\0"; + + for (i=0;i < x->cnt ; i ++) + { + switch (x->ops[i].kind) + { + case xd_filled_polygon : + case xd_unfilled_polygon : + case xd_filled_bezier: + case xd_unfilled_bezier: + case xd_polyline: + for (j=0;j < x->ops[i].u.polygon.cnt; j++) + { + x->ops[i].u.polygon.pts[j].x=x->ops[i].u.polygon.pts[j].x-dx; + x->ops[i].u.polygon.pts[j].y=x->ops[i].u.polygon.pts[j].y-dy; + x->ops[i].u.polygon.pts[j].z=x->ops[i].u.polygon.pts[j].z-dz; + } + break; + case xd_filled_ellipse : + case xd_unfilled_ellipse : + x->ops[i].u.ellipse.x=x->ops[i].u.ellipse.x-dx; + x->ops[i].u.ellipse.y=x->ops[i].u.ellipse.y-dy; + // x->ops[i].u.ellipse.z=x->ops[i].u.ellipse.z-dz; + break; + case xd_text: + x->ops[i].u.text.x=x->ops[i].u.text.x-dx; + x->ops[i].u.text.y=x->ops[i].u.text.y-dy; + // x->ops[i].u.text.z=x->ops[i].u.text.z-dz; + break; + case xd_image : + x->ops[i].u.image.pos.x=x->ops[i].u.image.pos.x-dx; + x->ops[i].u.image.pos.y=x->ops[i].u.image.pos.y-dy; + // x->ops[i].u.image.pos.z=x->ops[i].u.image.pos.z-dz; + break; + } + } + view.GLx=view.GLx2; + view.GLy=view.GLy2; + return sprintXDot (x); + + +} +extern char* offset_spline(xdot* x,float dx,float dy,float headx,float heady) +{ +/* int i=0; + Agnode_t* headn,tailn; + Agedge_t* e; + e=x->obj; //assume they are all edges, check function name + headn=aghead(e); + tailn=agtail(e); + + for (i=0; i < x->cnt ; i ++) //more than 1 splines ,possible + { + switch (x->ops[i].kind) + { + case xd_filled_polygon : + case xd_unfilled_polygon : + case xd_filled_bezier: + case xd_unfilled_bezier: + case xd_polyline: + if( ((custom_object_data*)AGDATA((headn)->obj))->Selected==1) && + ((custom_object_data*)AGDATA((tailn)->obj))->Selected==1) ) + { + for (j=0;j < x->ops[i].u.polygon.cnt; j++) + { + + x->ops[i].u.polygon.pts[j].x=x->ops[i].u.polygon.pts[j].x+dx; + x->ops[i].u.polygon.pts[j].y=x->ops[i].u.polygon.pts[j].y+dy; + x->ops[i].u.polygon.pts[j].z=x->ops[i].u.polygon.pts[j].z+dz; + } + } + break; + }*/ +} + + + + +//OpenGL extension +void drawXdot (xdot* xDot,int param) +{ + int id=0; + int id2=0; + + for (id=0; id < xDot->cnt ; id ++) + { + xDot->ops[id].parentxdot=xDot; + execOp (&xDot->ops[id],param); + + } + if ( ((custom_object_data*)AGDATA(xDot->obj))->Preselected == 1) + select_object (view.g[view.activeGraph],xDot->obj); + ((custom_object_data*)AGDATA(xDot->obj))->Preselected =0; +} +void execOp (xdot_op* op,int param) +{ + op->drawfunc(op,param); +} + + +void drawXdotwithattr(void* p,char* attr,int param) +{ + xdot* xDot; + if(xDot=parseXDot (agget(p, attr))) + { + xDot->obj=p; + drawXdot(xDot,param); + freeXDot (xDot); + } +} +void drawXdotwithattrs(void* e,int param) +{ + + + drawXdotwithattr(e,"_draw_",param); + drawXdotwithattr(e,"_ldraw_",param); + drawXdotwithattr(e,"_hdraw_",param); + drawXdotwithattr(e,"_tdraw_",param); + drawXdotwithattr(e,"_hldraw_",param); + drawXdotwithattr(e,"_tldraw_",param); + +} +void drawGraph(Agraph_t *g) +{ + Agnode_t *v; + Agedge_t *e; + Agraph_t *s; + int param=0; + + for (s = agfstsubg(g); s; s = agnxtsubg(s)) + { + + ((custom_object_data*)AGDATA(s))->selectionflag=0; + if( ((custom_object_data*)AGDATA(s))->Selected==1) + param=1; + else + param=0; + drawXdotwithattrs(s,param); + } + + for (v = agfstnode(g); v; v = agnxtnode(g, v)) + { + if( ((custom_object_data*)AGDATA(v))->Selected==1) + param=1; + else + param=0; + ((custom_object_data*)AGDATA(v))->selectionflag=0; + drawXdotwithattr(v,"_draw_",param); + drawXdotwithattr(v,"_ldraw_",param); + for (e = agfstout(g,v) ; e ; e = agnxtout (g,e)) + { + ((custom_object_data*)AGDATA(e))->selectionflag=0; + if( ((custom_object_data*)AGDATA(e))->Selected==1) + param=1; + else + param=0; + + drawXdotwithattrs(e,param); + + } + } + if((view.Selection.Active>0) && (!SignalBlock)) + { + view.Selection.Active=0; + drawGraph(g); + SignalBlock=1; + expose_event (drawing_area,NULL,NULL); + SignalBlock=0; + } + +} +void drawTopViewGraph3(Agraph_t *g) +{ +// DWORD t1,t2; + char* pch; + Agnode_t *v; + Agedge_t *e; + Agraph_t *s; + char buf [100]; + GLfloat a,b; + glPointSize(2); +// t1=GetTickCount(); +// glBegin(GL_POINTS); + for (v = agfstnode(g); v; v = agnxtnode(g, v)) + { + //use pos to put dots +/* if( ((custom_object_data*)AGDATA(v))->Selected==1) + glColor4f(view.selectColor.R,view.selectColor.G,view.selectColor.B,view.selectColor.A); + else + glColor4f(view.penColor.R,view.penColor.G,view.penColor.B,view.penColor.A); + strcpy(buf,agget(v, "pos")); + a=atof(strtok (buf,"," )); + b=atof(strtok (NULL,"," )); + glVertex3f(a ,b,0.0); */ + + } +// glEnd(); +// t2=GetTickCount(); +// printf("recorded tickcounts %d-%d \n", t1,t2); +// printf("iterating time (NODES):%d \n", t2-t1); + + + //draw edges +/* glBegin(GL_LINES); + for (v = agfstnode(g); v; v = agnxtnode(g, v)) + { + for (e = agfstout(g,v) ; e ; e = agnxtout (g,e)) + { + if( ((custom_object_data*)AGDATA(e))->Selected==1) + glColor4f(view.selectColor.R,view.selectColor.G,view.selectColor.B,view.selectColor.A); + else + glColor4f(view.penColor.R,view.penColor.G,view.penColor.B,view.penColor.A); + strcpy(buf,agget(aghead(e), "pos")); + a=atof(strtok (buf,"," )); + b=atof(strtok (NULL,"," )); + glVertex3f(a ,b,0.0); + strcpy(buf,agget(agtail(e), "pos")); + a=atof(strtok (buf,"," )); + b=atof(strtok (NULL,"," )); + glVertex3f(a ,b,0.0); + } + } + glEnd(); */ +} +void PrepareTopview2(Agraph_t *g) +{ + float a,b; + char* pch; + Agnode_t *v; + Agedge_t *e; + int ind,ind2; + char buf[100]; + ind=0;ind2=0; + for (v = agfstnode(g); v; v = agnxtnode(g, v)) + { + + strcpy(buf,agget(v, "pos")); + a=atof(strtok (buf,"," )); + b=atof(strtok (NULL,"," )); + + TopViewPointsX[ind]=a; + TopViewPointsY[ind]=b; + + + for (e = agfstout(g,v) ; e ; e = agnxtout (g,e)) + { + strcpy(buf,agget(aghead(e), "pos")); + a=atof(strtok (buf,"," )); + b=atof(strtok (NULL,"," )); + TopViewEdgesHeadX[ind2]=a; + TopViewEdgesHeadY[ind2]=b; + strcpy(buf,agget(agtail(e), "pos")); + a=atof(strtok (buf,"," )); + b=atof(strtok (NULL,"," )); + TopViewEdgesTailX[ind2]=a; + TopViewEdgesTailY[ind2]=b; + ind2++; + } + ind++; + } + TopViewNodeCount=ind; + TopViewEdgeCount=ind2; +} +void drawTopViewGraph2(Agraph_t *g) +{ +// DWORD t1,t2; + int ind=0; + glPointSize(3); + glBegin(GL_POINTS); + for (ind=0;ind < TopViewNodeCount;ind ++) + { + glVertex3f(TopViewPointsX[ind] ,TopViewPointsY[ind],0.0); + } + glEnd(); + glBegin(GL_LINES); + for (ind=0;ind < TopViewEdgeCount;ind ++) + { +// glColor4f(view.selectColor.R,view.selectColor.G,view.selectColor.B,view.selectColor.A); + glVertex3f(TopViewEdgesHeadX[ind],TopViewEdgesHeadY[ind],0.0); + glVertex3f(TopViewEdgesTailX[ind],TopViewEdgesTailY[ind],0.0); + + } + glEnd(); +} diff --git a/lib/xdot/xdot.h b/lib/xdot/xdot.h new file mode 100755 index 000000000..e234f306a --- /dev/null +++ b/lib/xdot/xdot.h @@ -0,0 +1,122 @@ +/* vim:set shiftwidth=4 ts=8: */ + +/********************************************************** +* This software is part of the graphviz package * +* http://www.graphviz.org/ * +* * +* Copyright (c) 1994-2007 AT&T Corp. * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Corp. * +* * +* Information and Software Systems Research * +* AT&T Research, Florham Park NJ * +**********************************************************/ + +#ifndef XDOT_H +#define XDOT_H +#include +#ifdef _WIN32 +#include +#include +#endif +//#include "draw.h" +#include + +//#include +#include "cgraph.h" + +typedef struct _TextTexture { + GLuint name; + GLsizei size; + GLvoid *texels; +} TextTexture; + +typedef enum { + xd_left, xd_center, xd_right +} xdot_align; + +typedef struct { + int x, y,z; //z is constant +} xdot_point; + +typedef struct { + int x, y, w, h; +} xdot_rect; + +typedef struct { + int cnt; + xdot_point* pts; +} xdot_polyline; + + +typedef struct { + TextTexture* texture; + int x, y; + xdot_align align; + int width; + char* text; + GLuint name; + GLsizei size; + GLvoid *texels; +} xdot_text; + +typedef struct { + xdot_rect pos; + char* name; +} xdot_image; + +typedef struct { + float size; + char* name; +} xdot_font; + +typedef enum { + xd_filled_ellipse, xd_unfilled_ellipse, + xd_filled_polygon, xd_unfilled_polygon, + xd_filled_bezier, xd_unfilled_bezier, + xd_polyline, xd_text, + xd_fill_color, xd_pen_color, xd_font, xd_style, xd_image +} xdot_kind; + + +typedef struct _xdot_op xdot_op; +typedef void (*drawfunc_t)(xdot_op*, int); + +struct _xdot_op{ + xdot_kind kind; + union { + xdot_rect ellipse; /* xd_filled_ellipse, xd_unfilled_ellipse */ + xdot_polyline polygon; /* xd_filled_polygon, xd_unfilled_polygon */ + xdot_polyline polyline; /* xd_polyline */ + xdot_polyline bezier; /* xd_filled_bezier, xd_unfilled_bezier */ + xdot_text text; /* xd_text */ + xdot_image image; /* xd_image */ + char* color; /* xd_fill_color, xd_pen_color */ + xdot_font font; /* xd_font */ + char* style; /* xd_style */ + } u; + drawfunc_t drawfunc; + void* parentxdot; //points to owner xdot +}; + +void execOp (xdot_op* op,int param); +typedef struct { + int cnt; + xdot_op* ops; + void* obj; //cgraph object, used for selection + int selectionflag; //used for rectangular selection (not x) if -1 cannot be selected +} xdot; + +extern xdot* parseXDot (char*); +extern char* sprintXDot (xdot*); +extern void fprintXDot (FILE*, xdot*); +extern void freeXDot (xdot*); +extern void drawXdot (xdot*,int param); +extern void drawGraph(Agraph_t *g); +extern void drawTopViewGraph3(Agraph_t *g); +extern Agnode_t* createNode(char* label,xdot_point); +extern void PrepareTopview2(Agraph_t *g); +extern char* move_xdot(void* obj,xdot* x,int dx,int dy,int dz); +extern char* offset_spline(xdot* x,float dx,float dy,float headx,float heady); +#endif