} a;
struct {
node_t* n;
- box* bp;
+ boxf* bp;
} s;
} inside_t;
typedef struct port { /* internal edge endpoint specification */
point p; /* aiming point relative to node center */
double theta; /* slope in radians */
- box *bp; /* if not null, points to bbox of
+ boxf *bp; /* if not null, points to bbox of
* rectangular area that is port target
*/
boolean defined; /* if true, edge has port info at this end */
typedef struct textlabel_t {
char *text, *fontname, *fontcolor;
double fontsize;
- pointf dimen;
- point p;
- pointf d; /* delta from resizing */
+ pointf dimen; /* the diagonal size of the label (estimated by layout) */
+ pointf space; /* the diagonal size of the space for the label */
+ /* the rendered label is aligned in this box */
+ /* space does not include pad or margin */
+ pointf pos; /* the center of the space for the label */
union {
struct {
textpara_t *para;
} txt;
htmllabel_t *html;
} u;
- boolean set; /* true if position is set */
- boolean html; /* true if html label */
+ char valign; /* 't' 'c' 'b' */
+ boolean set; /* true if position is set */
+ boolean html; /* true if html label */
} textlabel_t;
typedef struct polygon_t { /* mutable shape information for a node */
/* for "record" shapes */
typedef struct field_t {
point size; /* its dimension */
- box b; /* its placement in node's coordinates */
+ boxf b; /* its placement in node's coordinates */
int n_flds;
textlabel_t *lp; /* n_flds == 0 */
struct field_t **fld; /* n_flds > 0 */
return atoi(p);
}
-point dotneato_closest(splines * spl, point p)
+pointf dotneato_closest(splines * spl, pointf pt)
{
int i, j, k, besti, bestj;
double bestdist2, d2, dlow2, dhigh2; /* squares of distances */
double low, high, t;
- pointf c[4], pt2, pt;
- point rv;
+ pointf c[4], pt2;
bezier bz;
besti = bestj = -1;
bestdist2 = 1e+38;
- P2PF(p, pt);
for (i = 0; i < spl->size; i++) {
bz = spl->list[i];
for (j = 0; j < bz.size; j++) {
dlow2 = DIST2(pt2, pt);
}
} while (1);
- PF2P(pt2, rv);
- return rv;
+ return pt2;
}
point spline_at_y(splines * spl, int y)
/* addLabelBB:
*/
-static box addLabelBB(box bb, textlabel_t * lp, boolean flipxy)
+static boxf addLabelBB(boxf bb, textlabel_t * lp, boolean flipxy)
{
- int width, height;
- point p = lp->p;
- int min, max;
+ double width, height;
+ pointf p = lp->pos;
+ double min, max;
if (flipxy) {
- height = ROUND(lp->dimen.x);
- width = ROUND(lp->dimen.y);
+ height = lp->dimen.x;
+ width = lp->dimen.y;
}
else {
- width = ROUND(lp->dimen.x);
- height = ROUND(lp->dimen.y);
+ width = lp->dimen.x;
+ height = lp->dimen.y;
}
- min = p.x - width / 2;
- max = p.x + width / 2;
+ min = p.x - width / 2.;
+ max = p.x + width / 2.;
if (min < bb.LL.x)
bb.LL.x = min;
if (max > bb.UR.x)
bb.UR.x = max;
- min = p.y - height / 2;
- max = p.y + height / 2;
+ min = p.y - height / 2.;
+ max = p.y + height / 2.;
if (min < bb.LL.y)
bb.LL.y = min;
if (max > bb.UR.y)
*/
void updateBB(graph_t * g, textlabel_t * lp)
{
- GD_bb(g) = addLabelBB(GD_bb(g), lp, GD_flip(g));
+ boxf BF;
+ box B = GD_bb(g);
+
+ B2BF(B,BF);
+ BF = addLabelBB(BF, lp, GD_flip(g));
+ BF2B(BF, GD_bb(g));
}
/* compute_bb:
node_t *n;
edge_t *e;
box b, bb;
+ boxf BF;
+#ifdef SPLINESF
+ pointf ptf;
+#endif
point pt, s2;
int i, j;
continue;
for (i = 0; i < ED_spl(e)->size; i++) {
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];
+#endif
EXPANDBP(bb,pt);
}
}
- if (ED_label(e) && ED_label(e)->set)
- bb = addLabelBB(bb, ED_label(e), GD_flip(g));
+ if (ED_label(e) && ED_label(e)->set) {
+ B2BF(bb,BF);
+ BF = addLabelBB(BF, ED_label(e), GD_flip(g));
+ BF2B(BF,bb);
+ }
}
}
sx = lp->dimen.x / 2.;
sy = lp->dimen.y / 2.;
- bb.LL.x = lp->p.x - sx;
- bb.UR.x = lp->p.x + sx;
- bb.LL.y = lp->p.y - sy;
- bb.UR.y = lp->p.y + sy;
+ bb.LL.x = lp->pos.x - sx;
+ bb.UR.x = lp->pos.x + sx;
+ bb.LL.y = lp->pos.y - sy;
+ bb.UR.y = lp->pos.y + sy;
return OVERLAP(b, bb);
}
extern char* scanEntity (char* t, agxbuf* xb);
extern pointf Bezier(pointf *, int, double, pointf *, pointf *);
- extern point dotneato_closest(splines * spl, point p);
+ extern pointf dotneato_closest(splines * spl, pointf p);
extern point neato_closest(splines * spl, point p);
extern point spline_at_y(splines * spl, int y);
if (ND_alg(n)) {
edge_t* fe = (edge_t*)ND_alg(n);
assert (ED_label(fe));
- ED_label(fe)->p = ND_coord_i(n);
+ P2PF(ND_coord_i(n), ED_label(fe)->pos);
}
if ((ND_node_type(n) != NORMAL) &&
(sinfo.splineMerge(n) == FALSE))
e = ED_to_orig(e));
dimen = ED_label(e)->dimen;
width = GD_flip(n->graph) ? dimen.y : dimen.x;
- ED_label(e)->p.x = ND_coord_i(n).x + width / 2.0;
- ED_label(e)->p.y = ND_coord_i(n).y;
+ ED_label(e)->pos.x = ND_coord_i(n).x + width / 2.0;
+ ED_label(e)->pos.y = ND_coord_i(n).y;
}
static void
}
BF2B(bb, GD_bb(g));
if (ED_label(e)) {
- ED_label(e)->p = transform(ED_label(auxe)->p, del, GD_flip(g));
+ point pt;
+ PF2P(ED_label(auxe)->pos, pt);
+ pt = transform(pt, del, GD_flip(g));
+ P2PF(pt, ED_label(e)->pos);
updateBB(g, ED_label(e));
}
}
for (f = ED_to_virt(e); ED_to_virt(f); f = ED_to_virt(f));
ln = f->tail;
- ED_label(e)->p = ND_coord_i(ln);
+ P2PF(ND_coord_i(ln), ED_label(e)->pos);
if (et == ET_LINE) {
point startp, endp, lp;
startp = add_points(ND_coord_i(tn), ED_tail_port(e).p);
endp = add_points(ND_coord_i(hn), ED_head_port(e).p);
- lp = ED_label(e)->p;
+ PF2P(ED_label(e)->pos, lp);
lp.y -= (ED_label(e)->dimen.y)/2.0;
points[1] = points[0] = startp;
points[2] = points[3] = points[4] = lp;
height = dimen.y;
}
- lp = ED_label(e)->p;
+ PF2P(ED_label(e)->pos, lp);
if (leftOf (endp,startp,lp)) {
lp.x += width/2.0;
lp.y -= height/2.0;
static void set_elabel(edge_t * e, textlabel_t * l, char *name)
{
double x, y;
- point pt;
char *lp;
lp = agget(e, name);
if (lp && (sscanf(lp, "%lf,%lf", &x, &y) == 2)) {
- pt.x = (int) (x);
- pt.y = (int) (y);
- l->p = pt;
+ l->pos = pointfof(x, y);
l->set = TRUE;
}
}
graph_t *mg;
edge_t *me;
char *s;
- point p;
+ double x, y;
if (GD_label(g) && G_lp) {
s = agxget(g, G_lp->index);
- if (sscanf(s, "%d,%d", &p.x, &p.y) == 2) {
+ if (sscanf(s, "%lf,%lf", &x, &y) == 2) {
+ GD_label(g)->pos = pointfof(x, y);
GD_label(g)->set = TRUE;
- GD_label(g)->p = p;
}
}
}
if (ED_label(e) && ED_label(e)->set) {
- ED_label(e)->p.x -= offset.x;
- ED_label(e)->p.y -= offset.y;
+ ED_label(e)->pos.x -= offset.x;
+ ED_label(e)->pos.y -= offset.y;
}
if (ED_head_label(e) && ED_head_label(e)->set) {
- ED_head_label(e)->p.x -= offset.x;
- ED_head_label(e)->p.y -= offset.y;
+ ED_head_label(e)->pos.x -= offset.x;
+ ED_head_label(e)->pos.y -= offset.y;
}
if (ED_tail_label(e) && ED_tail_label(e)->set) {
- ED_tail_label(e)->p.x -= offset.x;
- ED_tail_label(e)->p.y -= offset.y;
+ ED_tail_label(e)->pos.x -= offset.x;
+ ED_tail_label(e)->pos.y -= offset.y;
}
}
GD_bb(g).LL.y -= offset.y;
if (GD_label(g) && GD_label(g)->set) {
- GD_label(g)->p.x -= offset.x;
- GD_label(g)->p.y -= offset.y;
+ GD_label(g)->pos.x -= offset.x;
+ GD_label(g)->pos.y -= offset.y;
}
for (i = 1; i <= GD_n_cluster(g); i++)
* Find midpoint of polyline.
* pp and pq are set to the endpoints of the line segment containing it.
*/
-static point
+static pointf
polylineMidpoint (splines* spl, point* pp, point* pq)
{
bezier bz;
int i, j, k;
double d, dist = 0;
- point m;
pointf pf, qf, mf;
for (i = 0; i < spl->size; i++) {
*pq = bz.list[k];
mf.x = ((qf.x*dist) + (pf.x*(d-dist)))/d;
mf.y = ((qf.y*dist) + (pf.y*(d-dist)))/d;
- PF2P(mf, m);
- return m;
+ return mf;
}
else
dist -= d;
}
}
assert (FALSE); /* should never get here */
- return m;
+ return mf;
}
#define LEFTOF(a,b,c) (((a.y - b.y)*(c.x - b.x) - (c.y - b.y)*(a.x - b.x)) > 0)
{
int et = EDGE_TYPE (e->head->graph->root);
point p, q;
- point d; /* midpoint of segment p-q */
+ pointf d; /* midpoint of segment p-q */
point ld;
- point sp;
point del;
pointf spf;
double f, ht, wd, dist2;
if ((p.x == q.x) && (p.y == q.y)) { /* degenerate spline */
p = rp;
q = rq;
- sp = p;
+ P2PF(p, spf);
}
else if (et == ET_SPLINE) {
- d.x = (q.x + p.x) / 2;
- d.y = (p.y + q.y) / 2;
- sp = dotneato_closest(ED_spl(e), d);
+ d.x = (q.x + p.x) / 2.;
+ d.y = (p.y + q.y) / 2.;
+ spf = dotneato_closest(ED_spl(e), d);
}
else { /* ET_PLINE or ET_LINE */
- sp = polylineMidpoint (ED_spl(e), &p, &q);
+ spf = polylineMidpoint (ED_spl(e), &p, &q);
}
del.x = q.x - p.x;
del.y = q.y - p.y;
dist2 = del.x*del.x + del.y*del.y;
ht = (ED_label(e)->dimen.y + 2)/2.0;
- spf.x = sp.x;
- spf.y = sp.y;
if (dist2) {
wd = (MIN(ED_label(e)->dimen.x + 2, MAXLABELWD))/2.0;
- leftOf = LEFTOF(p, q, sp);
+ leftOf = LEFTOF(p, q, spf);
if ((leftOf && (del.y >= 0)) || (!leftOf && (del.y < 0))) {
if (del.x*del.y >= 0)
ht *= -1;
ld.y = -ht;
}
- ED_label(e)->p.x = spf.x + ld.x;
- ED_label(e)->p.y = spf.y + ld.y;
+ ED_label(e)->pos.x = spf.x + ld.x;
+ ED_label(e)->pos.y = spf.y + ld.y;
ED_label(e)->set = TRUE;
updateBB(e->tail->graph, ED_label(e));
}
double adj = 0.0;
int j, sides;
pointf polyp;
- box b;
+ boxf b;
point pt;
field_t *fld;
epsf_t *desc;
}
if (ED_label(e) && ED_label(e)->set) {
- ED_label(e)->p.x *= xf;
- ED_label(e)->p.y *= yf;
+ ED_label(e)->pos.x *= xf;
+ ED_label(e)->pos.y *= yf;
}
if (ED_head_label(e) && ED_head_label(e)->set) {
- ED_head_label(e)->p.x += delh.x;
- ED_head_label(e)->p.y += delh.y;
+ ED_head_label(e)->pos.x += delh.x;
+ ED_head_label(e)->pos.y += delh.y;
}
if (ED_tail_label(e) && ED_tail_label(e)->set) {
- ED_tail_label(e)->p.x += delt.x;
- ED_tail_label(e)->p.y += delt.y;
+ ED_tail_label(e)->pos.x += delt.x;
+ ED_tail_label(e)->pos.y += delt.y;
}
}
GD_bb(g).LL.y *= yf;
if (GD_label(g) && GD_label(g)->set) {
- GD_label(g)->p.x *= xf;
- GD_label(g)->p.y *= yf;
+ GD_label(g)->pos.x *= xf;
+ GD_label(g)->pos.y *= yf;
}
for (i = 1; i <= GD_n_cluster(g); i++)
return rv;
}
-static Point makeScaledPoint(int x, int y)
+static Point makeScaledPoint(double x, double y)
{
Point rv;
rv.x = PS2INCH(x);
int sides;
Point *verts;
polygon_t *poly;
- box b;
+ boxf b;
if (ND_clust(n)) {
Point b;
sides = 4;
- b.x = ND_width(n) / 2.0 + (xmargin);
- b.y = ND_height(n) / 2.0 + (ymargin);
+ b.x = ND_width(n) / 2.0 + xmargin;
+ b.y = ND_height(n) / 2.0 + ymargin;
pp->kind = BOX;
verts = N_GNEW(sides, Point);
PUTPT(verts[0], b.x, b.y);
int sides;
Point *verts;
polygon_t *poly;
- box b;
+ boxf b;
if (ND_clust(n)) {
Point b;
* K. Freivalds et al., GD0'01, LNCS 2265, pp. 378-391.
*/
-#include <render.h>
-#include <pack.h>
-#include <pointset.h>
#include <math.h>
+#include "render.h"
+#include "pack.h"
+#include "pointset.h"
#define C 100 /* Max. avg. polyomino size */
bezier bz;
if (ED_label(e))
- MOVEPT(ED_label(e)->p);
+ MOVEPT(ED_label(e)->pos);
if (ED_head_label(e))
- MOVEPT(ED_head_label(e)->p);
+ MOVEPT(ED_head_label(e)->pos);
if (ED_tail_label(e))
- MOVEPT(ED_tail_label(e)->p);
+ MOVEPT(ED_tail_label(e)->pos);
if (ED_spl(e) == NULL)
return;
GD_bb(g) = bb;
if (GD_label(g))
- MOVEPT(GD_label(g)->p);
+ MOVEPT(GD_label(g)->pos);
for (i = 1; i <= GD_n_cluster(g); i++) {
subg = GD_clust(g)[i];