From c3f689918259acd4924df65bd125045cfb1341eb Mon Sep 17 00:00:00 2001 From: "Emden R. Gansner" Date: Thu, 17 Apr 2014 10:19:12 -0400 Subject: [PATCH] Add (undocumented) prototype implementation of edge labels that align with the edge. This only works with ordinary labels; only in svg; there is no handling of space or geometry issues. --- lib/common/emit.c | 2 ++ lib/common/labels.c | 2 ++ lib/gvc/gvcjob.h | 1 + plugin/core/gvrender_core_svg.c | 39 ++++++++++++++++++++++++++------- 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/lib/common/emit.c b/lib/common/emit.c index a87fdecce..d29533776 100644 --- a/lib/common/emit.c +++ b/lib/common/emit.c @@ -2461,6 +2461,8 @@ static void emit_begin_edge(GVJ_t * job, edge_t * e, char** styles) obj->type = EDGE_OBJTYPE; obj->u.e = e; obj->emit_state = EMIT_EDRAW; + if (ED_label(e) && !ED_label(e)->html && mapBool(agget(e,"labelaligned"),FALSE)) + obj->labeledgealigned = TRUE; /* We handle the edge style and penwidth here because the width * is needed below for calculating polygonal image maps diff --git a/lib/common/labels.c b/lib/common/labels.c index 157ec2dbd..78e346221 100644 --- a/lib/common/labels.c +++ b/lib/common/labels.c @@ -255,6 +255,8 @@ void emit_label(GVJ_t * job, emit_state_t emit_state, textlabel_t * lp) p.y = lp->pos.y + lp->dimen.y / 2.0 - lp->fontsize; break; } + if (obj->labeledgealigned) + p.y -= lp->pos.y; for (i = 0; i < lp->u.txt.nspans; i++) { switch (lp->u.txt.span[i].just) { case 'l': diff --git a/lib/gvc/gvcjob.h b/lib/gvc/gvcjob.h index cc317c955..c58ae79f5 100644 --- a/lib/gvc/gvcjob.h +++ b/lib/gvc/gvcjob.h @@ -241,6 +241,7 @@ extern "C" { int explicit_edgetarget:1; int explicit_tailurl:1; int explicit_headurl:1; + int labeledgealigned:1; /* primary mapped region - node shape, edge labels */ map_shape_t url_map_shape; diff --git a/plugin/core/gvrender_core_svg.c b/plugin/core/gvrender_core_svg.c index 68502c97e..85d8247fd 100644 --- a/plugin/core/gvrender_core_svg.c +++ b/plugin/core/gvrender_core_svg.c @@ -57,12 +57,22 @@ static void svg_bzptarray(GVJ_t * job, pointf * A, int n) char c; c = 'M'; /* first point */ - for (i = 0; i < n; i++) { - gvprintf(job, "%c%g,%g", c, A[i].x, -A[i].y); - if (i == 0) - c = 'C'; /* second point */ - else - c = ' '; /* remaining points */ + if (A[0].x <= A[n-1].x) { + for (i = 0; i < n; i++) { + gvprintf(job, "%c%g,%g", c, A[i].x, -A[i].y); + if (i == 0) + c = 'C'; /* second point */ + else + c = ' '; /* remaining points */ + } + } else { + for (i = n-1; i >= 0; i--) { + gvprintf(job, "%c%g,%g", c, A[i].x, -A[i].y); + if (i == 0) + c = 'C'; /* second point */ + else + c = ' '; /* remaining points */ + } } } @@ -364,7 +374,8 @@ static void svg_textspan(GVJ_t * job, pointf p, textspan_t * span) break; } p.y += span->yoffset_centerline; - gvprintf(job, " x=\"%g\" y=\"%g\"", p.x, -p.y); + if (!obj->labeledgealigned) + gvprintf(job, " x=\"%g\" y=\"%g\"", p.x, -p.y); pA = span->font->postscript_alias; if (pA) { switch (GD_fontnames(job->gvc->g)) { @@ -440,7 +451,13 @@ static void svg_textspan(GVJ_t * job, pointf p, textspan_t * span) assert(0); /* internal error */ } gvputs(job, ">"); + if (obj->labeledgealigned) { + gvprintf (job, "", xml_string(obj->id)); + gvprintf (job, "", -p.y); + } gvputs(job, xml_string0(span->str, TRUE)); + if (obj->labeledgealigned) + gvprintf (job, ""); gvputs(job, "\n"); } @@ -558,7 +575,8 @@ static void svg_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start, int arrow_at_end, int filled) { - int gid = 0; + int gid = 0; + obj_state_t *obj = job->obj; if (filled == GRADIENT) { gid = svg_gradstyle(job, A, n); @@ -566,6 +584,11 @@ svg_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start, gid = svg_rgradstyle(job, A, n); } gvputs(job, "labeledgealigned) { + gvputs(job, " id=\""); + gvputs(job, xml_string(obj->id)); + gvputs(job, "_p\" "); + } svg_grstyle(job, filled, gid); gvputs(job, " d=\""); svg_bzptarray(job, A, n); -- 2.40.0