* Compute the bounding box containing the graphs.
* We can just use the bounding boxes of the graphs.
*/
-box compBB(Agraph_t ** gs, int cnt)
+boxf compBB(Agraph_t ** gs, int cnt)
{
- box bb, bb2;
+ boxf bb, bb2;
int i;
bb = GD_bb(gs[0]);
Agraph_t *g;
int cnt;
pack_info pinfo;
- box bb;
GVC_t * gvc;
init(argc, argv);
/* compute new top-level bb and set */
if (DOPACK) {
- bb = compBB(gs, cnt);
- GD_bb(g) = bb;
+ GD_bb(g) = compBB(gs, cnt);
dotneato_postprocess(g);
attach_attrs(g);
}
gvc->pagedir = p;
/* bounding box */
- B2BF(GD_bb(g),gvc->bb);
+ gvc->bb = GD_bb(g);
/* clusters have peripheries */
G_peripheries = agfindattr(g, "peripheries");
void emit_clusters(GVJ_t * job, Agraph_t * g, int flags)
{
int c, istyle, filled;
- boxf BF;
pointf AF[4];
char *color, *fillcolor, *pencolor, **style, *s;
graph_t *sg;
sg = GD_clust(g)[c];
if (clust_in_layer(job, sg) == FALSE)
continue;
- B2BF(GD_bb(sg), BF);
/* when mapping, detect events on clusters after sub_clusters */
if (flags & EMIT_CLUSTERS_LAST)
emit_clusters(job, sg, flags);
setColorScheme (agget (sg, "colorscheme"));
gvrender_begin_context(job);
if (doAnchor && !(flags & EMIT_CLUSTERS_LAST)) {
- emit_map_rect(job, BF);
+ emit_map_rect(job, GD_bb(sg));
gvrender_begin_anchor(job, obj->url, obj->tooltip, obj->target);
}
filled = FALSE;
if (istyle & ROUNDED) {
if (late_int(sg, G_peripheries, 1, 0) || filled) {
- AF[0] = BF.LL;
- AF[2] = BF.UR;
+ AF[0] = GD_bb(sg).LL;
+ AF[2] = GD_bb(sg).UR;
AF[1].x = AF[2].x;
AF[1].y = AF[0].y;
AF[3].x = AF[0].x;
gvrender_set_pencolor(job, pencolor);
gvrender_set_fillcolor(job, fillcolor);
if (late_int(sg, G_peripheries, 1, 0))
- gvrender_box(job, BF, filled);
+ gvrender_box(job, GD_bb(sg), filled);
else if (filled) {
if (fillcolor && fillcolor != pencolor)
gvrender_set_pencolor(job, fillcolor);
- gvrender_box(job, BF, filled);
+ gvrender_box(job, GD_bb(sg), filled);
}
}
if ((lab = GD_label(sg)))
if (doAnchor) {
if (flags & EMIT_CLUSTERS_LAST) {
- emit_map_rect(job, BF);
+ emit_map_rect(job, GD_bb(sg));
gvrender_begin_anchor(job, obj->url, obj->tooltip, obj->target);
}
gvrender_end_anchor(job);
static void setYInvert(graph_t * g)
{
if (Y_invert) {
- Y_off = GD_bb(g).UR.y + GD_bb(g).LL.y;
+ Y_off = ROUND(GD_bb(g).UR.y + GD_bb(g).LL.y);
YF_off = PS2INCH(Y_off);
}
}
node_t *n;
edge_t *e;
bezier bz;
- point pt;
+ pointf pt;
char *lbl;
// setup_graph(job, g);
char buf[BUFSIZ];
pointf pt;
- sprintf(buf, "%d,%d,%d,%d", GD_bb(g).LL.x, YDIR(GD_bb(g).LL.y),
- GD_bb(g).UR.x, YDIR(GD_bb(g).UR.y));
+ sprintf(buf, "%.3g,%.3g,%.3g,%.3g", GD_bb(g).LL.x, YFDIR(GD_bb(g).LL.y),
+ GD_bb(g).UR.x, YFDIR(GD_bb(g).UR.y));
agset(g, "bb", buf);
if (GD_label(g) && GD_label(g)->text[0]) {
pt = GD_label(g)->pos;
static int Rankdir;
static boolean Flip;
-static point Offset;
+static pointf Offset;
static void place_flip_graph_label(graph_t * g);
#define M1 \
"/pathbox {\n\
- /Y exch %d sub def\n\
- /X exch %d sub def\n\
- /y exch %d sub def\n\
- /x exch %d sub def\n\
+ /Y exch %.3g sub def\n\
+ /X exch %.3g sub def\n\
+ /y exch %.3g sub def\n\
+ /x exch %.3g sub def\n\
newpath x y moveto\n\
X y lineto\n\
X Y lineto\n\
x Y lineto\n\
closepath stroke\n \
} def\n\
-/dbgstart { gsave %d %d translate } def\n\
+/dbgstart { gsave %.3g %.3g translate } def\n\
/arrowlength 10 def\n\
/arrowwidth arrowlength 2 div def\n\
/arrowhead {\n\
X Y moveto\n\
x y makearrow\n\
} def\n"
+
#define M2 \
"/pathbox {\n\
- /X exch neg %d sub def\n\
- /Y exch %d sub def\n\
- /x exch neg %d sub def\n\
- /y exch %d sub def\n\
+ /X exch neg %.3g sub def\n\
+ /Y exch %.3g sub def\n\
+ /x exch neg %.3g sub def\n\
+ /y exch %.3g sub def\n\
newpath x y moveto\n\
X y lineto\n\
X Y lineto\n\
void translate_bb(graph_t * g, int rankdir)
{
int c;
- box bb, new_bb;
+ boxf bb, new_bb;
bb = GD_bb(g);
if (rankdir == RANKDIR_LR || rankdir == RANKDIR_BT) {
- new_bb.LL = map_point(pointof(bb.LL.x, bb.UR.y));
- new_bb.UR = map_point(pointof(bb.UR.x, bb.LL.y));
+ new_bb.LL = map_pointf(pointfof(bb.LL.x, bb.UR.y));
+ new_bb.UR = map_pointf(pointfof(bb.UR.x, bb.LL.y));
} else {
- new_bb.LL = map_point(pointof(bb.LL.x, bb.LL.y));
- new_bb.UR = map_point(pointof(bb.UR.x, bb.UR.y));
+ new_bb.LL = map_pointf(pointfof(bb.LL.x, bb.LL.y));
+ new_bb.UR = map_pointf(pointfof(bb.UR.x, bb.UR.y));
}
GD_bb(g) = new_bb;
if (GD_label(g)) {
* flipped drawing has been transposed, so we don't have
* to worry about switching x and y.
*/
-static void place_root_label(graph_t * g, point d)
+static void place_root_label(graph_t * g, pointf d)
{
- point p;
+ pointf p;
if (GD_label_pos(g) & LABEL_AT_RIGHT) {
p.x = GD_bb(g).UR.x - d.x / 2;
p.y = GD_bb(g).LL.y + d.y / 2;
}
- P2PF(p, GD_label(g)->pos);
+ GD_label(g)->pos = p;
GD_label(g)->set = TRUE;
}
*/
void dotneato_postprocess(Agraph_t * g)
{
- int diff;
- pointf dimen;
- point d = { 0, 0 };
+ double diff;
+ pointf dimen = {0., 0.};
Rankdir = GD_rankdir(g);
Flip = GD_flip(g);
if (GD_label(g) && !GD_label(g)->set) {
dimen = GD_label(g)->dimen;
PAD(dimen);
- PF2P(dimen, d);
if (Flip) {
if (GD_label_pos(g) & LABEL_AT_TOP) {
- GD_bb(g).UR.x += d.y;
+ GD_bb(g).UR.x += dimen.y;
} else {
- GD_bb(g).LL.x -= d.y;
+ GD_bb(g).LL.x -= dimen.y;
}
- if (d.x > GD_bb(g).UR.y - GD_bb(g).LL.y) {
- diff = d.x - (GD_bb(g).UR.y - GD_bb(g).LL.y);
- diff = diff / 2;
+ if (dimen.x > (GD_bb(g).UR.y - GD_bb(g).LL.y)) {
+ diff = dimen.x - (GD_bb(g).UR.y - GD_bb(g).LL.y);
+ diff = diff / 2.;
GD_bb(g).LL.y -= diff;
GD_bb(g).UR.y += diff;
}
} else {
if (GD_label_pos(g) & LABEL_AT_TOP) {
if (Rankdir == RANKDIR_TB)
- GD_bb(g).UR.y += d.y;
+ GD_bb(g).UR.y += dimen.y;
else
- GD_bb(g).LL.y -= d.y;
+ GD_bb(g).LL.y -= dimen.y;
} else {
if (Rankdir == RANKDIR_TB)
- GD_bb(g).LL.y -= d.y;
+ GD_bb(g).LL.y -= dimen.y;
else
- GD_bb(g).UR.y += d.y;
+ GD_bb(g).UR.y += dimen.y;
}
- if (d.x > GD_bb(g).UR.x - GD_bb(g).LL.x) {
- diff = d.x - (GD_bb(g).UR.x - GD_bb(g).LL.x);
- diff = diff / 2;
+ if (dimen.x > (GD_bb(g).UR.x - GD_bb(g).LL.x)) {
+ diff = dimen.x - (GD_bb(g).UR.x - GD_bb(g).LL.x);
+ diff = diff / 2.;
GD_bb(g).LL.x -= diff;
GD_bb(g).UR.x += diff;
}
Offset = GD_bb(g).LL;
break;
case RANKDIR_LR:
- Offset = pointof(-GD_bb(g).UR.y, GD_bb(g).LL.x);
+ Offset = pointfof(-GD_bb(g).UR.y, GD_bb(g).LL.x);
break;
case RANKDIR_BT:
- Offset = pointof(GD_bb(g).LL.x, -GD_bb(g).UR.y);
+ Offset = pointfof(GD_bb(g).LL.x, -GD_bb(g).UR.y);
break;
case RANKDIR_RL:
- Offset = pointof(GD_bb(g).LL.y, GD_bb(g).LL.x);
+ Offset = pointfof(GD_bb(g).LL.y, GD_bb(g).LL.x);
break;
}
translate_drawing(g);
if (GD_label(g) && !GD_label(g)->set)
- place_root_label(g, d);
+ place_root_label(g, dimen);
if (Show_boxes) {
char buf[BUFSIZ];
static void place_flip_graph_label(graph_t * g)
{
int c;
- point p, d;
-#ifdef OLD
- int maxx, minx;
- int maxy, miny;
- pointf dimen;
-#endif
+ pointf p, d;
if ((g != g->root) && (GD_label(g)) && !GD_label(g)->set) {
if (GD_label_pos(g) & LABEL_AT_TOP) {
- d = GD_border(g)[RIGHT_IX];
+ P2PF(GD_border(g)[RIGHT_IX], d);
p.x = GD_bb(g).UR.x - d.x / 2;
-#ifdef OLD
- maxx = GD_bb(g).UR.x + d.y;
- GD_bb(g).UR.x = maxx;
- if (GD_bb(g->root).UR.x < maxx)
- GD_bb(g->root).UR.x = maxx;
-#endif
} else {
- d = GD_border(g)[LEFT_IX];
+ P2PF(GD_border(g)[LEFT_IX], d);
p.x = GD_bb(g).LL.x + d.x / 2;
-#ifdef OLD
- minx = GD_bb(g).LL.x - d.y;
- GD_bb(g).LL.x = minx;
- if (GD_bb(g->root).LL.x > minx)
- GD_bb(g->root).LL.x = minx;
-#endif
}
if (GD_label_pos(g) & LABEL_AT_RIGHT) {
p.y = GD_bb(g).LL.y + d.y / 2;
-#ifdef OLD
- maxy = p.y + d.x / 2;
- if (GD_bb(g->root).UR.y < maxy)
- GD_bb(g->root).UR.y = maxy;
-#endif
} else if (GD_label_pos(g) & LABEL_AT_LEFT) {
p.y = GD_bb(g).UR.y - d.y / 2;
-#ifdef OLD
- miny = p.y - d.x / 2;
- if (GD_bb(g->root).LL.y > miny)
- GD_bb(g->root).LL.y = miny;
-#endif
} else {
p.y = (GD_bb(g).LL.y + GD_bb(g).UR.y) / 2;
-#ifdef OLD
- maxy = p.y + d.x / 2;
- miny = p.y - d.x / 2;
-#endif
}
-
- P2PF(p, GD_label(g)->pos);
+ GD_label(g)->pos = p;
GD_label(g)->set = TRUE;
}
void place_graph_label(graph_t * g)
{
int c;
-#ifdef OLD
- int minx, maxx;
-#endif
- point p, d;
+ pointf p, d;
if ((g != g->root) && (GD_label(g)) && !GD_label(g)->set) {
if (GD_label_pos(g) & LABEL_AT_TOP) {
- d = GD_border(g)[TOP_IX];
+ P2PF(GD_border(g)[TOP_IX], d);
p.y = GD_bb(g).UR.y - d.y / 2;
} else {
- d = GD_border(g)[BOTTOM_IX];
+ P2PF(GD_border(g)[BOTTOM_IX], d);
p.y = GD_bb(g).LL.y + d.y / 2;
}
if (GD_label_pos(g) & LABEL_AT_RIGHT) {
p.x = GD_bb(g).UR.x - d.x / 2;
-#ifdef OLD
- minx = p.x - d.x / 2;
- if (GD_bb(g).LL.x > minx)
- GD_bb(g).LL.x = minx;
- if (GD_bb(g->root).LL.x > minx)
- GD_bb(g->root).LL.x = minx;
-#endif
} else if (GD_label_pos(g) & LABEL_AT_LEFT) {
p.x = GD_bb(g).LL.x + d.x / 2;
-#ifdef OLD
- maxx = p.x + d.x / 2;
- if (GD_bb(g).UR.x < maxx)
- GD_bb(g).UR.x = maxx;
- if (GD_bb(g->root).UR.x < maxx)
- GD_bb(g->root).UR.x = maxx;
-#endif
} else {
p.x = (GD_bb(g).LL.x + GD_bb(g).UR.x) / 2;
-#ifdef OLD
- maxx = p.x + d.x / 2;
- minx = p.x - d.x / 2;
- if (GD_bb(g).UR.x < maxx)
- GD_bb(g).UR.x = maxx;
- if (GD_bb(g).LL.x > minx)
- GD_bb(g).LL.x = minx;
- if (GD_bb(g->root).UR.x < maxx)
- GD_bb(g->root).UR.x = maxx;
- if (GD_bb(g->root).LL.x > minx)
- GD_bb(g->root).LL.x = minx;
-#endif
}
- P2PF(p, GD_label(g)->pos);
+ GD_label(g)->pos = p;
GD_label(g)->set = TRUE;
}
dimen = ND_label(n)->dimen;
/* minimal whitespace around label */
-// FIXME - is this an FP safe test?
- if ((dimen.x > 0.0) || (dimen.y > 0.0)) {
+ if (ROUND(abs(dimen.x)) || ROUND(abs(dimen.y))) {
/* padding */
if ((p = agget(n, "margin"))) {
i = sscanf(p, "%lf,%lf", &marginx, &marginy);
int start, end, i, clipTail, clipHead;
graph_t *g;
edge_t *orig;
- boxf *tbox, *hbox, bb;
+ boxf *tbox, *hbox;
inside_t inside_context;
tn = fe->tail;
if (ps[end].x != ps[end + 3].x || ps[end].y != ps[end + 3].y)
break;
arrow_clip(fe, hn, ps, &start, &end, newspl, info);
- B2BF(GD_bb(g), bb);
for (i = start; i < end + 4; ) {
pointf cp[4];
newspl->list[i - start] = ps[i];
P2PF(ps[i], cp[2]);
i++;
P2PF(ps[i], cp[3]);
- update_bb_bz(&bb, cp);
+ update_bb_bz(&GD_bb(g), cp);
}
- BF2B(bb, GD_bb(g));
newspl->size = end - start + 4;
}
/* to generate code */
layout_t *drawing;
textlabel_t *label; /* if the cluster has a title */
- box bb; /* bounding box */
+ boxf bb; /* bounding box */
point border[4]; /* sizes of margins for graph labels */
unsigned char gui_state; /* Graph state for GUI ops */
unsigned char has_labels;
*/
void updateBB(graph_t * g, textlabel_t * lp)
{
- boxf BF;
- box B = GD_bb(g);
-
- B2BF(B,BF);
- BF = addLabelBB(BF, lp, GD_flip(g));
- BF2B(BF, GD_bb(g));
+ GD_bb(g) = addLabelBB(GD_bb(g), lp, GD_flip(g));
}
/* compute_bb:
{
node_t *n;
edge_t *e;
- box b, bb;
+ boxf b, bb;
boxf BF;
-#ifdef SPLINESF
- pointf ptf;
+ pointf ptf, s2;
+#ifndef SPLINESF
+ point pt;
#endif
- point pt, s2;
int i, j;
- bb.LL = pointof(INT_MAX, INT_MAX);
- bb.UR = pointof(-INT_MAX, -INT_MAX);
+ bb.LL = pointfof(INT_MAX, INT_MAX);
+ bb.UR = pointfof(-INT_MAX, -INT_MAX);
for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
- pt = coord(n);
- s2.x = ND_xsize(n) / 2 + 1;
- s2.y = ND_ysize(n) / 2 + 1;
- b.LL = sub_points(pt, s2);
- b.UR = add_points(pt, s2);
+ P2PF(coord(n), ptf);
+ s2.x = ND_xsize(n) / 2. + 1;
+ s2.y = ND_ysize(n) / 2. + 1;
+ b.LL = sub_pointfs(ptf, s2);
+ b.UR = add_pointfs(ptf, s2);
EXPANDBB(bb,b);
for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
for (j = 0; j < ED_spl(e)->list[i].size; j++) {
#ifdef SPLINESF
ptf = ED_spl(e)->list[i].list[j];
- PF2P(ptf, pt);
#else
pt = ED_spl(e)->list[i].list[j];
+ P2PF(pt, ptf);
#endif
- EXPANDBP(bb,pt);
+ EXPANDBP(bb,ptf);
}
}
if (ED_label(e) && ED_label(e)->set) {
- B2BF(bb,BF);
- BF = addLabelBB(BF, ED_label(e), GD_flip(g));
- BF2B(BF,bb);
+ bb = addLabelBB(bb, ED_label(e), GD_flip(g));
}
}
}
for (i = 1; i <= GD_n_cluster(g); i++) {
- EXPANDBB(bb,GD_clust(g)[i]->u.bb);
+ B2BF(GD_clust(g)[i]->u.bb, BF);
+ EXPANDBB(bb,BF);
}
GD_bb(g) = bb;
#include "dot.h"
+#define P2PF(p, pf) (pf.x = p.x, pf.y = p.y)
+#define PF2P(pf, p) (p.x = ROUND (pf.x), p.y = ROUND (pf.y))
/* midPt:
* Return midpoint between two given points.
* the box bp. Assume cp is outside the box, and pp is
* on or in the box.
*/
-static point boxIntersect(point pp, point cp, box * bp)
+static point boxIntersect(point pp, point cp, boxf * bp)
{
point ipp;
double ppx = pp.x;
double ppy = pp.y;
double cpx = cp.x;
double cpy = cp.y;
- point ll = bp->LL;
- point ur = bp->UR;
+ point ll;
+ point ur;
+ PF2P(bp->LL, ll);
+ PF2P(bp->UR, ur);
if (cp.x < ll.x) {
ipp.x = ll.x;
ipp.y = pp.y + (int) ((ipp.x - ppx) * (ppy - cpy) / (ppx - cpx));
/* inBox:
* Returns true if p is on or in box bb
*/
-static int inBox(point p, box * bb)
+static int inBox(point p, boxf * bb)
{
- return ((p.x >= bb->LL.x) && (p.x <= bb->UR.x) &&
- (p.y >= bb->LL.y) && (p.y <= bb->UR.y));
+ return (((double)p.x >= bb->LL.x) && ((double)p.x <= bb->UR.x) &&
+ ((double)p.y >= bb->LL.y) && ((double)p.y <= bb->UR.y));
}
/* getCluster:
*/
static double
findVertical(pointf * pts, double tmin, double tmax,
- int xcoord, int ymin, int ymax)
+ double xcoord, double ymin, double ymax)
{
pointf Left[4];
pointf Right[4];
return -1.0;
/* if 1 crossing and on the line x = xcoord */
- if ((no_cross == 1) && (ROUND(pts[3].x) == xcoord)) {
+ if ((no_cross == 1) && (ROUND(pts[3].x) == ROUND(xcoord))) {
if ((ymin <= pts[3].y) && (pts[3].y <= ymax)) {
return tmax;
} else
*/
static double
findHorizontal(pointf * pts, double tmin, double tmax,
- int ycoord, int xmin, int xmax)
+ double ycoord, double xmin, double xmax)
{
pointf Left[4];
pointf Right[4];
return -1.0;
/* if 1 crossing and on the line y = ycoord */
- if ((no_cross == 1) && (ROUND(pts[3].y) == ycoord)) {
+ if ((no_cross == 1) && (ROUND(pts[3].y) == ROUND(ycoord))) {
if ((xmin <= pts[3].x) && (pts[3].x <= xmax)) {
return tmax;
} else
return t;
return findHorizontal(Right, (tmin + tmax) / 2.0, tmax, ycoord, xmin,
xmax);
-
}
-#define P2PF(p, pf) (pf.x = p.x, pf.y = p.y)
-#define PF2P(pf, p) (p.x = ROUND (pf.x), p.y = ROUND (pf.y))
-
/* splineIntersect:
* Given four spline control points and a box,
* find the shortest portion of the spline from
* with ipts[3] being on the box, and 1 is returned. Otherwise, ipts
* is left unchanged and 0 is returned.
*/
-static int splineIntersect(point * ipts, box * bb)
+static int splineIntersect(point * ipts, boxf * bb)
{
double tmin = 2.0;
double t;
return 1;
} else
return 0;
-
}
/* makeCompoundEdge:
int starti = 0, endi = 0; /* index of first and last control point */
node_t *head;
node_t *tail;
- box *bb;
+ boxf *bb;
int i, j;
int size;
point pts[4];
free(bez->list);
free(bez);
ED_spl(e)->list = nbez;
-
}
/* dot_compoundEdges:
int i, j, midx, midy, leftx, rightx;
point del;
edge_t* hvye = NULL;
- boxf bb;
g = e0->tail->graph;
tn = e0->tail, hn = e0->head;
bz->eflag = auxbz->eflag;
bz->ep = transform(auxbz->ep, del, 0);
}
- B2BF(GD_bb(g), bb);
for (j = 0; j < auxbz->size; ) {
point pt;
pointf cp[4];
j++;
pt = transform(auxbz->list[j], del, GD_flip(g));
P2PF(pt,cp[3]);
- update_bb_bz(&bb, cp);
+ update_bb_bz(&GD_bb(g), cp);
}
- BF2B(bb, GD_bb(g));
if (ED_label(e)) {
point pt;
PF2P(ED_label(auxe)->pos, pt);
static int cl_vninside(graph_t * cl, node_t * n)
{
- return (BETWEEN(GD_bb(cl).LL.x, ND_coord_i(n).x, GD_bb(cl).UR.x) &&
- BETWEEN(GD_bb(cl).LL.y, ND_coord_i(n).y, GD_bb(cl).UR.y));
+ return (BETWEEN(GD_bb(cl).LL.x, (double)(ND_coord_i(n).x), GD_bb(cl).UR.x) &&
+ BETWEEN(GD_bb(cl).LL.y, (double)(ND_coord_i(n).y), GD_bb(cl).UR.y));
}
/* returns the cluster of (adj) that interferes with n,
static box maximal_bbox(spline_info_t* sp, node_t* vn, edge_t* ie, edge_t* oe)
{
- int nb, b;
+ double b, nb;
graph_t *g = vn->graph, *left_cl, *right_cl;
node_t *left, *right;
box rv;
left_cl = right_cl = NULL;
/* give this node all the available space up to its neighbors */
- b = ND_coord_i(vn).x - ND_lw_i(vn) - FUDGE;
+ b = (double)(ND_coord_i(vn).x - ND_lw_i(vn) - FUDGE);
if ((left = neighbor(vn, ie, oe, -1))) {
if ((left_cl = cl_bound(vn, left)))
- nb = GD_bb(left_cl).UR.x + sp->Splinesep;
+ nb = GD_bb(left_cl).UR.x + (double)(sp->Splinesep);
else {
- nb = ND_coord_i(left).x + ND_mval(left);
+ nb = (double)(ND_coord_i(left).x + ND_mval(left));
if (ND_node_type(left) == NORMAL)
- nb += GD_nodesep(g) / 2;
+ nb += GD_nodesep(g) / 2.;
else
- nb += sp->Splinesep;
+ nb += (double)(sp->Splinesep);
}
if (nb < b)
b = nb;
- rv.LL.x = b;
+ rv.LL.x = ROUND(b);
} else
- rv.LL.x = MIN(b, sp->LeftBound);
+ rv.LL.x = MIN(ROUND(b), sp->Splinesep);
/* we have to leave room for our own label! */
if ((ND_node_type(vn) == VIRTUAL) && (ND_label(vn)))
- b = ND_coord_i(vn).x + 10;
+ b = (double)(ND_coord_i(vn).x + 10);
else
- b = ND_coord_i(vn).x + ND_rw_i(vn) + FUDGE;
+ b = (double)(ND_coord_i(vn).x + ND_rw_i(vn) + FUDGE);
if ((right = neighbor(vn, ie, oe, 1))) {
if ((right_cl = cl_bound(vn, right)))
- nb = GD_bb(right_cl).LL.x - sp->Splinesep;
+ nb = GD_bb(right_cl).LL.x - (double)(sp->Splinesep);
else {
nb = ND_coord_i(right).x - ND_lw_i(right);
if (ND_node_type(right) == NORMAL)
- nb -= GD_nodesep(g) / 2;
+ nb -= GD_nodesep(g) / 2.;
else
- nb -= sp->Splinesep;
+ nb -= (double)(sp->Splinesep);
}
if (nb > b)
b = nb;
- rv.UR.x = b;
+ rv.UR.x = ROUND(b);
} else
- rv.UR.x = MAX(b, sp->RightBound);
+ rv.UR.x = MAX(ROUND(b), sp->RightBound);
if ((ND_node_type(vn) == VIRTUAL) && (ND_label(vn)))
rv.UR.x -= ND_rw_i(vn);
{
int r, c, x, offset;
node_t *v;
- point LL, UR;
+ pointf LL, UR;
if (g == g->root) {
- LL.x = INT_MAX;
- UR.x = -INT_MAX;
+ LL.x = (double)(INT_MAX);
+ UR.x = (double)(-INT_MAX);
for (r = GD_minrank(g); r <= GD_maxrank(g); r++) {
int rnkn = GD_rank(g)[r].n;
if (rnkn == 0)
for (c = 1; (ND_node_type(v) != NORMAL) && c < rnkn; c++)
v = GD_rank(g)[r].v[c];
if (ND_node_type(v) == NORMAL) {
- x = ND_coord_i(v).x - ND_lw_i(v);
+ x = (double)(ND_coord_i(v).x - ND_lw_i(v));
LL.x = MIN(LL.x, x);
}
else continue;
v = GD_rank(g)[r].v[rnkn - 1];
for (c = rnkn-2; ND_node_type(v) != NORMAL; c--)
v = GD_rank(g)[r].v[c];
- x = ND_coord_i(v).x + ND_rw_i(v);
+ x = (double)(ND_coord_i(v).x + ND_rw_i(v));
UR.x = MAX(UR.x, x);
}
offset = CL_OFFSET;
for (c = 1; c <= GD_n_cluster(g); c++) {
- x = GD_clust(g)[c]->u.bb.LL.x - offset;
+ x = (double)(GD_clust(g)[c]->u.bb.LL.x - offset);
LL.x = MIN(LL.x, x);
- x = GD_clust(g)[c]->u.bb.UR.x + offset;
+ x = (double)(GD_clust(g)[c]->u.bb.UR.x + offset);
UR.x = MAX(UR.x, x);
}
} else {
- LL.x = ND_rank(GD_ln(g));
- UR.x = ND_rank(GD_rn(g));
+ LL.x = (double)(ND_rank(GD_ln(g)));
+ UR.x = (double)(ND_rank(GD_rn(g)));
}
- LL.y = ND_rank(root)[GD_maxrank(g)].v[0]->u.coord.y - GD_ht1(g);
- UR.y = ND_rank(root)[GD_minrank(g)].v[0]->u.coord.y + GD_ht2(g);
+ LL.y = (double)(ND_rank(root)[GD_maxrank(g)].v[0]->u.coord.y - GD_ht1(g));
+ UR.y = (double)(ND_rank(root)[GD_minrank(g)].v[0]->u.coord.y + GD_ht2(g));
GD_bb(g).LL = LL;
GD_bb(g).UR = UR;
}
static Ppoly_t *makeClustObs(graph_t * g, expand_t* pm)
{
Ppoly_t *obs = NEW(Ppoly_t);
- box bb = GD_bb(g);
+ boxf bb;
boxf newbb;
Ppoint_t ctr;
+ bb = GD_bb(g);
obs->pn = 4;
obs->ps = N_NEW(4, Ppoint_t);
#include <values.h>
#endif
#endif
-#include <tlayout.h>
-#include <neatoprocs.h>
-#include <adjust.h>
-#include <comp.h>
-#include <pack.h>
#include <assert.h>
-#include <clusteredges.h>
-#include <dbg.h>
+#include "tlayout.h"
+#include "neatoprocs.h"
+#include "adjust.h"
+#include "comp.h"
+#include "pack.h"
+#include "clusteredges.h"
+#include "dbg.h"
typedef struct {
graph_t* rootg; /* logical root; graph passed in to fdp_layout */
/* compute graph bounding box in points */
if (c_cnt) {
cg = *cp++;
- bb = GD_bb(cg);
+ BF2B(GD_bb(cg), bb);
if (c_cnt > 1) {
pt = *pp++;
bb.LL.x += pt.x;
bb.UR.x += pt.x;
bb.UR.y += pt.y;
while ((cg = *cp++)) {
- b = GD_bb(cg);
+ BF2B(GD_bb(cg), b);
pt = *pp++;
b.LL.x += pt.x;
b.LL.y += pt.y;
static void setBB(graph_t * g)
{
int i;
- GD_bb(g).LL = cvt2pt(BB(g).LL);
- GD_bb(g).UR = cvt2pt(BB(g).UR);
+ box bb;
+
+ bb.LL = cvt2pt(BB(g).LL);
+ bb.UR = cvt2pt(BB(g).UR);
+ B2BF(bb, GD_bb(g));
for (i = 1; i <= GD_n_cluster(g); i++) {
setBB(GD_clust(g)[i]);
}
bb.LL.y = bb.UR.y;
bb.UR.y = tmp;
}
- GD_bb(g) = bb;
+ B2BF(bb, GD_bb(g));
return 1;
} else
return 0;
static void translateG(Agraph_t * g, point offset)
{
int i;
+ pointf Offset;
- GD_bb(g).UR.x -= offset.x;
- GD_bb(g).UR.y -= offset.y;
- GD_bb(g).LL.x -= offset.x;
- GD_bb(g).LL.y -= offset.y;
+ P2PF(offset, Offset);
+ GD_bb(g).UR.x -= Offset.x;
+ GD_bb(g).UR.y -= Offset.y;
+ GD_bb(g).LL.x -= Offset.x;
+ GD_bb(g).LL.y -= Offset.y;
if (GD_label(g) && GD_label(g)->set) {
GD_label(g)->pos.x -= offset.x;
node_t *n;
edge_t *e;
pointf offset;
+ point ll;
- offset = cvt2ptf(GD_bb(g).LL);
+ PF2P(GD_bb(g).LL, ll);
+
+ offset = cvt2ptf(ll);
for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
ND_pos(n)[0] -= offset.x;
ND_pos(n)[1] -= offset.y;
for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
for (e = agfstout(g, n); e; e = agnxtout(g, e))
if (ED_spl(e))
- translateE(e, GD_bb(g).LL);
+ translateE(e, ll);
}
}
- translateG(g, GD_bb(g).LL);
+ translateG(g, ll);
}
/* init_nop:
/* At this point, all bounding boxes should be correctly defined.
* If necessary, we translate the graph to the origin.
*/
- if (adjust && (GD_bb(g).LL.x || GD_bb(g).LL.y))
+ if (adjust && (ROUND(abs(GD_bb(g).LL.x)) || ROUND(abs(GD_bb(g).LL.y))))
translate(g, posEdges);
if (!adjust) {
{
node_t *n;
pointf offset;
+ point ll;
+ P2PF(GD_bb(g).LL, ll);
compute_bb(g);
- offset = cvt2ptf(GD_bb(g).LL);
+ offset = cvt2ptf(ll);
for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
ND_pos(n)[0] -= offset.x;
ND_pos(n)[1] -= offset.y;
/* compute_bb(g); */
if (GD_drawing(g)->ratio_kind) {
/* normalize */
- assert(GD_bb(g).LL.x == 0);
- assert(GD_bb(g).LL.y == 0);
+ assert(ROUND(GD_bb(g).LL.x) == 0);
+ assert(ROUND(GD_bb(g).LL.y) == 0);
if (GD_flip(g)) {
- int t = GD_bb(g).UR.x;
+ double t = GD_bb(g).UR.x;
GD_bb(g).UR.x = GD_bb(g).UR.y;
GD_bb(g).UR.y = t;
}
/* fill is weird because both X and Y can stretch */
if (GD_drawing(g)->size.x <= 0)
return;
- xf = (double) GD_drawing(g)->size.x / (double) GD_bb(g).UR.x;
- yf = (double) GD_drawing(g)->size.y / (double) GD_bb(g).UR.y;
+ xf = (double) GD_drawing(g)->size.x / GD_bb(g).UR.x;
+ yf = (double) GD_drawing(g)->size.y / GD_bb(g).UR.y;
/* handle case where one or more dimensions is too big */
if ((xf < 1.0) || (yf < 1.0)) {
if (xf < yf) {
} else if (GD_drawing(g)->ratio_kind == R_EXPAND) {
if (GD_drawing(g)->size.x <= 0)
return;
- xf = (double) GD_drawing(g)->size.x / (double) GD_bb(g).UR.x;
- yf = (double) GD_drawing(g)->size.y / (double) GD_bb(g).UR.y;
+ xf = (double) GD_drawing(g)->size.x / GD_bb(g).UR.x;
+ yf = (double) GD_drawing(g)->size.y / GD_bb(g).UR.y;
if ((xf > 1.0) && (yf > 1.0)) {
double scale = MIN(xf, yf);
xf = yf = scale;
return;
} else if (GD_drawing(g)->ratio_kind == R_VALUE) {
desired = GD_drawing(g)->ratio;
- actual = ((double) GD_bb(g).UR.y) / ((double) GD_bb(g).UR.x);
+ actual = (GD_bb(g).UR.y) / (GD_bb(g).UR.x);
if (actual < desired) {
yf = desired / actual;
xf = 1.0;
PointSet *ps;
int W, H;
point UR, LL;
- box bb = GD_bb(g);
+ box bb;
int x, y;
+ BF2B(GD_bb(g), bb);
ps = newPS();
LL.x = center.x - margin;
eg = g;
ps = newPS();
- dx = center.x - GD_bb(g).LL.x;
- dy = center.y - GD_bb(g).LL.y;
+ dx = center.x - ROUND(GD_bb(g).LL.x);
+ dy = center.y - ROUND(GD_bb(g).LL.y);
if (pinfo->mode == l_clust) {
int i;
/* do bbox of top clusters */
for (i = 1; i <= GD_n_cluster(g); i++) {
subg = GD_clust(g)[i];
- bb = GD_bb(subg);
+ BF2B(GD_bb(subg), bb);
if ((bb.UR.x > bb.LL.x) && (bb.UR.y > bb.LL.y)) {
MOVEPT(bb.LL);
MOVEPT(bb.UR);
info->graph = g;
info->cells = pointsOf(ps);
info->nc = sizeOf(ps);
- W = GRID(GD_bb(g).UR.x - GD_bb(g).LL.x + 2 * margin, ssize);
- H = GRID(GD_bb(g).UR.y - GD_bb(g).LL.y + 2 * margin, ssize);
+ W = GRID(ROUND(GD_bb(g).UR.x - GD_bb(g).LL.x) + 2 * margin, ssize);
+ H = GRID(ROUND(GD_bb(g).UR.y - GD_bb(g).LL.y) + 2 * margin, ssize);
info->perim = W + H;
if (Verbose > 2) {
cells++;
}
- LL = GD_bb(info->graph).LL;
+ PF2P(GD_bb(info->graph).LL, LL);
place->x = step * x - LL.x;
place->y = step * y - LL.y;
if (i == 0) {
Agraph_t *g = info->graph;
- W = GRID(GD_bb(g).UR.x - GD_bb(g).LL.x + 2 * margin, step);
- H = GRID(GD_bb(g).UR.y - GD_bb(g).LL.y + 2 * margin, step);
+ W = GRID(ROUND(GD_bb(g).UR.x - GD_bb(g).LL.x) + 2 * margin, step);
+ H = GRID(ROUND(GD_bb(g).UR.y - GD_bb(g).LL.y) + 2 * margin, step);
if (fits(-W / 2, -H / 2, info, ps, place, step))
return;
}
if (fits(0, 0, info, ps, place, step))
return;
- W = GD_bb(info->graph).UR.x - GD_bb(info->graph).LL.x;
- H = GD_bb(info->graph).UR.y - GD_bb(info->graph).LL.y;
+ W = ROUND(GD_bb(info->graph).UR.x - GD_bb(info->graph).LL.x);
+ H = ROUND(GD_bb(info->graph).UR.y - GD_bb(info->graph).LL.y);
if (W >= H) {
for (bnd = 1;; bnd++) {
x = 0;
int i;
boolean *fixed = pinfo->fixed;
int fixed_cnt = 0;
- box fixed_bb = { {0, 0}, {0, 0} };
+ box bb, fixed_bb = { {0, 0}, {0, 0} };
point center;
if (ng <= 0)
Agraph_t *g = gs[i];
compute_bb(g);
if (fixed && fixed[i]) {
+ BF2B(GD_bb(g), bb);
if (fixed_cnt) {
- box bb = GD_bb(g);
fixed_bb.LL.x = MIN(bb.LL.x, fixed_bb.LL.x);
fixed_bb.LL.y = MIN(bb.LL.y, fixed_bb.LL.y);
fixed_bb.UR.x = MAX(bb.UR.x, fixed_bb.UR.x);
fixed_bb.UR.y = MAX(bb.UR.y, fixed_bb.UR.y);
} else
- fixed_bb = GD_bb(g);
+ fixed_bb = bb;
fixed_cnt++;
}
if (Verbose > 2) {
- fprintf(stderr, "bb[%s] %d %d %d %d\n", g->name, GD_bb(g).LL.x,
+ fprintf(stderr, "bb[%s] %.3g %.3g %.3g %.3g\n", g->name, GD_bb(g).LL.x,
GD_bb(g).LL.y, GD_bb(g).UR.x, GD_bb(g).UR.y);
}
}
static void shiftGraph(Agraph_t * g, int dx, int dy)
{
graph_t *subg;
- box bb = GD_bb(g);
+ boxf bb = GD_bb(g);
int i;
+ bb = GD_bb(g);
bb.LL.x += dx;
bb.UR.x += dx;
bb.LL.y += dy;
ret = packGraphs(ng, gs, root, info);
if (ret == 0) {
int i, j;
- box bb;
+ boxf bb;
graph_t* g;
compute_bb(root);
printer(&root);
walker(&root);
compute_bb(g);
- fprintf(stderr,"bb %d %d %d %d\n",
+ fprintf(stderr,"bb %.3g %.3g %.3g %.3g\n",
GD_bb(g).LL.x, GD_bb(g).LL.y, GD_bb(g).UR.x, GD_bb(g).UR.y);
dotneato_postprocess(g);
}