From: Emden Gansner Date: Wed, 25 Jul 2012 19:19:09 +0000 (-0400) Subject: Make sure object ids are unique. This is done in lib/common, using layer and page... X-Git-Tag: LAST_LIBGRAPH~32^2~366^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4377a07b33d00597e156cbcd44112ddb8ccdb7d2;p=graphviz Make sure object ids are unique. This is done in lib/common, using layer and page info. The svg renderer now just uses internal ids for gradient fills, and prepends "a_" to the object id for anchor ids. --- diff --git a/lib/common/emit.c b/lib/common/emit.c index bd00c9bd1..569c4632d 100644 --- a/lib/common/emit.c +++ b/lib/common/emit.c @@ -175,6 +175,20 @@ initMapData (GVJ_t* job, char* lbl, char* url, char* tooltip, char* target, char return assigned; } +static void +layerPagePrefix (GVJ_t* job, agxbuf* xb) +{ + char buf[128]; /* large enough for 2 decimal 64-bit ints and "page_," */ + if (job->layerNum > 1) { + agxbput (xb, job->gvc->layerIDs[job->layerNum]); + agxbputc (xb, '_'); + } + if ((job->pagesArrayElem.x > 0) || (job->pagesArrayElem.x > 0)) { + sprintf (buf, "page%d,%d_", job->pagesArrayElem.x, job->pagesArrayElem.y); + agxbput (xb, buf); + } +} + /* genObjId: * Use id of root graph if any, plus kind and internal id of object */ @@ -186,11 +200,20 @@ getObjId (GVJ_t* job, void* obj, agxbuf* xb) char* gid = GD_drawing(root)->id; long idnum; char* pfx; - char buf[30]; /* large enough for decimal 64-bit int */ + char buf[64]; /* large enough for a decimal 64-bit int */ + + layerPagePrefix (job, xb); id = agget(obj, "id"); - if (id && *id) - return id; + if (id && (*id != '\0')) { + agxbput (xb, id); + return agxbuse(xb); + } + + if ((obj != root) && gid) { + agxbput (xb, gid); + agxbputc (xb, '_'); + } switch (agobjkind(obj)) { #ifndef WITH_CGRAPH @@ -200,7 +223,10 @@ getObjId (GVJ_t* job, void* obj, agxbuf* xb) case AGRAPH: idnum = AGSEQ(obj); #endif - pfx = "graph"; + if (root == obj) + pfx = "graph"; + else + pfx = "clust"; break; case AGNODE: idnum = AGSEQ((Agnode_t*)obj); @@ -212,10 +238,6 @@ getObjId (GVJ_t* job, void* obj, agxbuf* xb) break; } - if (gid) { - agxbput (xb, gid); - agxbputc (xb, '_'); - } agxbput (xb, pfx); sprintf (buf, "%ld", idnum); agxbput (xb, buf); @@ -3303,12 +3325,30 @@ static void emit_end_graph(GVJ_t * job, graph_t * g) pop_obj_state(job); } +#define NotFirstPage(j) (((j)->layerNum>1)||((j)->pagesArrayElem.x > 0)||((j)->pagesArrayElem.x > 0)) + static void emit_page(GVJ_t * job, graph_t * g) { obj_state_t *obj = job->obj; int nump = 0, flags = job->flags; textlabel_t *lab; pointf *p = NULL; + char* saveid; + unsigned char buf[SMALLBUF]; + agxbuf xb; + + /* For the first page, we can use the values generated in emit_begin_graph. + * For multiple pages, we need to generate a new id. + */ + if (NotFirstPage(job)) { + agxbinit(&xb, SMALLBUF, buf); + saveid = obj->id; + layerPagePrefix (job, &xb); + agxbput (&xb, saveid); + obj->id = agxbuse(&xb); + } + else + saveid = NULL; setColorScheme (agget (g, "colorscheme")); setup_page(job, g); @@ -3348,7 +3388,7 @@ static void emit_page(GVJ_t * job, graph_t * g) emit_map_rect(job, job->clip); gvrender_begin_anchor(job, obj->url, obj->tooltip, obj->target, obj->id); } - if (numPhysicalLayers(job) == 1) + /* if (numPhysicalLayers(job) == 1) */ emit_background(job, g); if (GD_label(g)) emit_label(job, EMIT_GLABEL, GD_label(g)); @@ -3356,6 +3396,10 @@ static void emit_page(GVJ_t * job, graph_t * g) gvrender_end_anchor(job); emit_view(job,g,flags); gvrender_end_page(job); + if (saveid) { + agxbfree(&xb); + obj->id = saveid; + } } void emit_graph(GVJ_t * job, graph_t * g) diff --git a/plugin/core/gvrender_core_svg.c b/plugin/core/gvrender_core_svg.c index 37d523f3a..89dc89dfc 100644 --- a/plugin/core/gvrender_core_svg.c +++ b/plugin/core/gvrender_core_svg.c @@ -46,8 +46,6 @@ typedef enum { FORMAT_SVG, FORMAT_SVGZ, } format_type; static char *sdasharray = "5,2"; /* SVG dot array */ static char *sdotarray = "1,5"; -static int gradId; -static int anchorId; #ifndef HAVE_STRCASECMP extern int strcasecmp(const char *s1, const char *s2); @@ -297,7 +295,7 @@ svg_begin_anchor(GVJ_t * job, char *href, char *tooltip, char *target, { gvputs(job, "obj; @@ -478,7 +477,8 @@ static int svg_rgradstyle(GVJ_t * job, pointf * A, int n) pointf G[2]; float angle; int ifx, ify; - int id = gradId++; + static int rgradId; + int id = rgradId++; obj_state_t *obj = job->obj; angle = obj->gradient_angle * M_PI / 180; //angle of gradient line