}
}
-void emit_map_rect(GVJ_t *job, point LL, point UR)
+void emit_map_rect(GVJ_t *job, boxf b)
{
obj_state_t *obj = job->obj;
int flags = job->flags;
}
free(obj->url_map_p);
obj->url_map_p = p = N_NEW(obj->url_map_n, pointf);
- P2PF(LL,p[0]);
- P2PF(UR,p[1]);
+ p[0] = b.LL;
+ p[1] = b.UR;
if (! (flags & GVRENDER_DOES_TRANSFORM))
gvrender_ptf_A(job, p, p, 2);
if (! (flags & GVRENDER_DOES_MAP_RECTANGLE))
}
free(obj->url_map_p);
obj->url_map_p = p = N_NEW(obj->url_map_n, pointf);
- P2RECT(lab->p, p, lab->dimen.x / 2., lab->dimen.y / 2.);
+ P2RECT(lab->pos, p, lab->dimen.x / 2., lab->dimen.y / 2.);
if (! (flags & GVRENDER_DOES_TRANSFORM))
gvrender_ptf_A(job, p, p, 2);
if (! (flags & GVRENDER_DOES_MAP_RECTANGLE))
static void emit_attachment(GVJ_t * job, textlabel_t * lp, splines * spl)
{
pointf sz, AF[3];
- point p;
unsigned char *s;
for (s = (unsigned char *) (lp->text); *s; s++) {
return;
sz = lp->dimen;
- AF[0] = pointfof((double)(lp->p.x) + sz.x / 2., (double)(lp->p.y) - sz.y / 2.);
+ AF[0] = pointfof(lp->pos.x + sz.x / 2., lp->pos.y - sz.y / 2.);
AF[1] = pointfof(AF[0].x - sz.x, AF[0].y);
- p = dotneato_closest(spl, lp->p);
- P2PF(p,AF[2]);
+ AF[2] = dotneato_closest(spl, lp->pos);
/* Don't use edge style to draw attachment */
gvrender_set_style(job, job->gvc->defaultlinestyle);
/* Use font color to draw attachment
obj_state_t *obj = job->obj;
int nump = 0, flags = job->flags;
textlabel_t *lab;
- point p1, p2;
pointf *p = NULL;
setColorScheme (agget (g, "colorscheme"));
* or end_page of renderer.
*/
if (!(flags & EMIT_CLUSTERS_LAST) && (obj->url || obj->explicit_tooltip)) {
- PF2P(job->clip.LL, p1);
- PF2P(job->clip.UR, p2);
- emit_map_rect(job, p1, p2);
+ emit_map_rect(job, job->clip);
gvrender_begin_anchor(job, obj->url, obj->tooltip, obj->target);
}
if (job->numLayers == 1)
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, GD_bb(sg).LL, GD_bb(sg).UR);
+ emit_map_rect(job, BF);
gvrender_begin_anchor(job, obj->url, obj->tooltip, obj->target);
}
filled = FALSE;
gvrender_set_penwidth(job, penwidth);
}
- B2BF(GD_bb(sg), BF);
if (istyle & ROUNDED) {
if (late_int(sg, G_peripheries, 1, 0) || filled) {
AF[0] = BF.LL;
if (doAnchor) {
if (flags & EMIT_CLUSTERS_LAST) {
- emit_map_rect(job, GD_bb(sg).LL, GD_bb(sg).UR);
+ emit_map_rect(job, BF);
gvrender_begin_anchor(job, obj->url, obj->tooltip, obj->target);
}
gvrender_end_anchor(job);
return rv;
}
+boxf flip_rec_boxf(boxf b, pointf p)
+{
+ boxf rv;
+ /* flip box */
+ rv.UR.x = b.UR.y;
+ rv.UR.y = b.UR.x;
+ rv.LL.x = b.LL.y;
+ rv.LL.y = b.LL.x;
+ /* move box */
+ rv.LL.x += p.x;
+ rv.LL.y += p.y;
+ rv.UR.x += p.x;
+ rv.UR.y += p.y;
+ return rv;
+}
+
/* ptToLine2:
* Return distance from point p to line a-b squared.
*/
extern int boxf_contains(boxf, boxf);
extern box flip_rec_box(box b, point p);
+extern boxf flip_rec_boxf(boxf b, pointf p);
extern double ptToLine2 (pointf l1, pointf l2, pointf p);
#define DEFAULT_CELLSPACING 2
typedef struct {
- point p;
+ pointf pos;
htmlfont_t finfo;
void *obj;
graph_t *g;
static void
emit_htextparas(GVJ_t* job, int nparas, htextpara_t* paras, pointf p,
- double halfwidth_x, char* fname, double fsize, char* fcolor, box b)
+ double halfwidth_x, char* fname, double fsize, char* fcolor, boxf b)
{
int i,j;
- double tmp, center_x, left_x, right_x, fsize_;
+ double center_x, left_x, right_x, fsize_;
char *fname_ , *fcolor_;
textpara_t tl;
pointf p_ = {0.0, 0.0};
/* Initial p is in center of text block; set initial baseline
* to top of text block.
*/
- p_.y = p.y + (double)(b.UR.y-b.LL.y)/2.0;
- tmp = ROUND(p_.y); /* align with integer points */
- p_.y = (double)tmp;
+ p_.y = p.y + (b.UR.y-b.LL.y)/2.0;
gvrender_begin_context(job);
for(i=0; i<nparas; i++) {
fcolor = env->finfo.color;
halfwidth_x = ((double) (tp->box.UR.x - tp->box.LL.x)) / 2.0;
- p.x = env->p.x + ((double) (tp->box.UR.x + tp->box.LL.x)) / 2.0;
- p.y = env->p.y + ((double) (tp->box.UR.y + tp->box.LL.y)) / 2.0;
+ p.x = env->pos.x + ((double) (tp->box.UR.x + tp->box.LL.x)) / 2.0;
+ p.y = env->pos.y + ((double) (tp->box.UR.y + tp->box.LL.y)) / 2.0;
emit_htextparas(job, tp->nparas, tp->paras, p, halfwidth_x, fname,
fsize, fcolor, tp->box);
* from x to x+border will all pixels from x to x+border, and thus have
* width border+1.
*/
-static void doBorder(GVJ_t * job, char *color, int border, box B)
+static void doBorder(GVJ_t * job, char *color, int border, boxf BF)
{
pointf pt;
- boxf BF;
double wd, ht;
gvrender_begin_context(job);
gvrender_set_fillcolor(job, color);
gvrender_set_pencolor(job, color);
- B2BF(B, BF);
if (border == 1) {
gvrender_box(job, BF, 0);
} else {
gvrender_end_context(job);
}
-static void doFill(GVJ_t * job, char *color, box B)
+static void doFill(GVJ_t * job, char *color, boxf BF)
{
- boxf BF;
-
gvrender_set_fillcolor(job, color);
gvrender_set_pencolor(job, color);
- B2BF(B, BF);
gvrender_box(job, BF, 1);
}
* for nodes, edges, etc. ?
*/
static int
-initAnchor (GVJ_t* job, htmldata_t* data, box pts, htmlmap_data_t* save,
+initAnchor (GVJ_t* job, htmldata_t* data, boxf b, htmlmap_data_t* save,
int closePrev)
{
obj_state_t *obj = job->obj;
if (closePrev && (save->url || save->explicit_tooltip))
gvrender_end_anchor(job);
if (obj->url || obj->explicit_tooltip) {
- emit_map_rect(job, pts.LL, pts.UR);
+ emit_map_rect(job, b);
gvrender_begin_anchor(job, obj->url, obj->tooltip, obj->target);
}
}
static void
emit_html_tbl(GVJ_t * job, htmltbl_t * tbl, htmlenv_t * env)
{
- box pts = tbl->data.box;
- point p = env->p;
+ boxf pts = tbl->data.box;
+ pointf pos = env->pos;
htmlcell_t **cells = tbl->u.n.cells;
- htmlfont_t savef;
+ static htmlfont_t savef;
htmlmap_data_t saved;
int anchor; /* if true, we need to undo anchor settings. */
int doAnchor = (tbl->data.href || tbl->data.target);
if (tbl->font)
pushFontInfo(env, tbl->font, &savef);
- pts.LL.x += p.x;
- pts.UR.x += p.x;
- pts.LL.y += p.y;
- pts.UR.y += p.y;
+ pts.LL.x += pos.x;
+ pts.UR.x += pos.x;
+ pts.LL.y += pos.y;
+ pts.UR.y += pos.y;
if (doAnchor && !(job->flags & EMIT_CLUSTERS_LAST))
anchor = initAnchor(job, &tbl->data, pts, &saved, 1);
emit_html_img(GVJ_t * job, htmlimg_t * cp, htmlenv_t * env)
{
pointf A[4];
- box bb = cp->box;
+ boxf bb = cp->box;
char* scale;
- bb.LL.x += env->p.x;
- bb.LL.y += env->p.y;
- bb.UR.x += env->p.x;
- bb.UR.y += env->p.y;
+ bb.LL.x += env->pos.x;
+ bb.LL.y += env->pos.y;
+ bb.UR.x += env->pos.x;
+ bb.UR.y += env->pos.y;
- P2PF(bb.UR, A[0]);
- P2PF(bb.LL, A[2]);
+ A[0] = bb.UR;
+ A[2] = bb.LL;
A[1].x = A[2].x;
A[1].y = A[0].y;
A[3].x = A[0].x;
emit_html_cell(GVJ_t * job, htmlcell_t * cp, htmlenv_t * env)
{
htmlmap_data_t saved;
- box pts = cp->data.box;
- point p = env->p;
+ boxf pts = cp->data.box;
+ pointf pos = env->pos;
int inAnchor, doAnchor = (cp->data.href || cp->data.target);
- pts.LL.x += p.x;
- pts.UR.x += p.x;
- pts.LL.y += p.y;
- pts.UR.y += p.y;
+ pts.LL.x += pos.x;
+ pts.UR.x += pos.x;
+ pts.LL.y += pos.y;
+ pts.UR.y += pos.y;
if (doAnchor && !(job->flags & EMIT_CLUSTERS_LAST))
inAnchor = initAnchor(job, &cp->data, pts, &saved, 1);
htmlenv_t env;
allocObj (job);
- env.p = tp->p;
+ env.pos = tp->pos;
env.finfo.color = tp->fontcolor;
env.finfo.name = tp->fontname;
env.finfo.size = tp->fontsize;
* If successful, return pointer to port's box.
* Else return NULL.
*/
-box *html_port(node_t * n, char *pname, int* sides)
+boxf *html_port(node_t * n, char *pname, int* sides)
{
htmldata_t* tp;
htmllabel_t* lbl = ND_label(n)->u.html;
- box* rv = NULL;
+ boxf* rv = NULL;
if (lbl->kind == HTML_TEXT)
return NULL;
GD_has_images(env->g) = TRUE;
}
- img->box = b;
+ B2BF(b, img->box);
return rv;
}
size_html_cell(graph_t *g, htmlcell_t * cp, htmltbl_t * parent, htmlenv_t * env)
{
int rv;
- point sz, child_sz;
+ pointf sz, child_sz;
int margin;
cp->parent = parent;
closeGraphs(rowg, colg);
}
-static void pos_html_tbl(htmltbl_t *, box, int); /* forward declaration */
+static void pos_html_tbl(htmltbl_t *, boxf, int); /* forward declaration */
/* pos_html_img:
* Place image in cell
* storing allowed space handed by parent cell.
* How this space is used is handled in emit_html_img.
*/
-static void pos_html_img(htmlimg_t * cp, box pos)
+static void pos_html_img(htmlimg_t * cp, boxf pos)
{
cp->box = pos;
}
/* pos_html_cell:
*/
-static void pos_html_cell(htmlcell_t * cp, box pos, int sides)
+static void pos_html_cell(htmlcell_t * cp, boxf pos, int sides)
{
- int delx, dely;
- point oldsz;
- box cbox;
+ double delx, dely;
+ pointf oldsz;
+ boxf cbox;
if (!cp->data.pencolor)
cp->data.pencolor = cp->parent->data.pencolor;
* attribute indicating which external sides of the node
* are accessible to the table.
*/
-static void pos_html_tbl(htmltbl_t * tbl, box pos, int sides)
+static void pos_html_tbl(htmltbl_t * tbl, boxf pos, int sides)
{
- int x, y, delx, dely;
- int i, plus, extra, oldsz;
+ double x, y, delx, dely, extra, oldsz;
+ int i, plus;
htmlcell_t **cells = tbl->u.n.cells;
htmlcell_t *cp;
- box cbox;
+ boxf cbox;
if (tbl->u.n.parent && !tbl->data.pencolor)
tbl->data.pencolor = tbl->u.n.parent->data.pencolor;
/* change sizes to start positions and distribute extra space */
x = pos.LL.x + tbl->data.border + tbl->data.space;
extra = delx / (tbl->cc);
- plus = delx - extra * (tbl->cc);
+ plus = ROUND(delx - extra * (tbl->cc));
for (i = 0; i <= tbl->cc; i++) {
delx = tbl->widths[i] + extra + (i < plus ? 1 : 0);
tbl->widths[i] = x;
}
y = pos.UR.y - tbl->data.border - tbl->data.space;
extra = dely / (tbl->rc);
- plus = dely - extra * (tbl->rc);
+ plus = ROUND(dely - extra * (tbl->rc));
for (i = 0; i <= tbl->rc; i++) {
dely = tbl->heights[i] + extra + (i < plus ? 1 : 0);
tbl->heights[i] = y;
{
int i, wd, ht;
int rv = 0;
- htmlfont_t savef;
+ static htmlfont_t savef;
if (tbl->font)
pushFontInfo(env, tbl->font, &savef);
int make_html_label(graph_t *g, textlabel_t * lp, void *obj)
{
int rv;
- int wd2, ht2;
- box box;
+ double wd2, ht2;
+ boxf box;
htmllabel_t *lbl;
htmlenv_t env;
rv |= size_html_tbl(g, lbl->u.tbl, NULL, &env);
wd2 = (lbl->u.tbl->data.box.UR.x + 1) / 2;
ht2 = (lbl->u.tbl->data.box.UR.y + 1) / 2;
- box = boxof(-wd2, -ht2, wd2, ht2);
+ box = boxfof(-wd2, -ht2, wd2, ht2);
pos_html_tbl(lbl->u.tbl, box, BOTTOM | RIGHT | TOP | LEFT);
lp->dimen.x = box.UR.x - box.LL.x;
lp->dimen.y = box.UR.y - box.LL.y;
rv |= size_html_txt(g, lbl->u.txt, &env);
wd2 = (lbl->u.txt->box.UR.x + 1) / 2;
ht2 = (lbl->u.txt->box.UR.y + 1) / 2;
- box = boxof(-wd2, -ht2, wd2, ht2);
+ box = boxfof(-wd2, -ht2, wd2, ht2);
lbl->u.txt->box = box;
lp->dimen.x = box.UR.x - box.LL.x;
lp->dimen.y = box.UR.y - box.LL.y;
typedef struct {
htextpara_t *paras;
short nparas;
- box box;
+ boxf box;
} htmltxt_t;
typedef struct {
- box box;
+ boxf box;
char *src;
char *scale;
} htmlimg_t;
unsigned short flags;
unsigned short width;
unsigned short height;
- box box; /* its geometric placement in points */
+ boxf box; /* its geometric placement in points */
} htmldata_t;
#define HTML_UNSET 0
extern void free_html_text(htmltxt_t *);
extern void free_html_font(htmlfont_t*);
- extern box *html_port(node_t * n, char *pname, int* sides);
+ extern boxf *html_port(node_t * n, char *pname, int* sides);
extern int html_path(node_t * n, port* p, int side, box * rv, int *k);
extern int html_inside(node_t * n, pointf p, edge_t * e);
storeline(g, lp, line, 'n');
}
+ lp->space = lp->dimen;
return lp->dimen;
}
void emit_label(GVJ_t * job, emit_state_t emit_state, textlabel_t * lp)
{
obj_state_t *obj = job->obj;
- double halfwidth_x, center_x, left_x, right_x;
int i;
pointf p;
emit_state_t old_emit_state;
if (lp->u.txt.nparas < 1)
return;
- p.x = lp->p.x;
- p.y = lp->p.y;
-
- /* dimensions of box for label, no padding, adjusted for resizing */
- halfwidth_x = MAX(lp->d.x, (lp->dimen.x / 2.0));
-
- center_x = p.x;
- left_x = center_x - halfwidth_x;
- right_x = center_x + halfwidth_x;
-
- /* position for first para */
- p.y += (lp->dimen.y + lp->d.y) / 2.0 - lp->fontsize;
-
gvrender_begin_context(job);
gvrender_set_pencolor(job, lp->fontcolor);
gvrender_set_font(job, lp->fontname, lp->fontsize);
+ /* position for first para */
+ switch (lp->valign) {
+ case 't':
+ p.y = lp->pos.y + lp->space.y / 2.0 - lp->fontsize;
+ break;
+ case 'b':
+ p.y = lp->pos.y - lp->space.y / 2.0 + lp->dimen.y - lp->fontsize;
+ break;
+ case 'c':
+ default:
+ p.y = lp->pos.y + lp->dimen.y / 2.0 - lp->fontsize;
+ break;
+ }
for (i = 0; i < lp->u.txt.nparas; i++) {
switch (lp->u.txt.para[i].just) {
case 'l':
- p.x = left_x;
+ p.x = lp->pos.x - lp->space.x / 2.0;
break;
case 'r':
- p.x = right_x;
+ p.x = lp->pos.x + lp->space.x / 2.0;
break;
default:
case 'n':
- p.x = center_x;
+ p.x = lp->pos.x;
break;
}
gvrender_textpara(job, p, &(lp->u.txt.para[i]));
for (i = 0; (e = ND_tree_out(n).list[i]); i++) {
e_cnt++;
if (SLACK(e) > 0)
- fprintf(stderr, "not a tight tree %x", e);
+ fprintf(stderr, "not a tight tree %lx", (unsigned long int)e);
}
}
if ((n_cnt != Tree_node.size) || (e_cnt != Tree_edge.size))
for (i = 0; (e = ND_out(n).list[i]); i++) {
w = e->head;
if (ND_onstack(w)) {
- fprintf(stderr, "cycle: last edge %x %s(%x) %s(%x)\n",
- e,n->name,n,w->name,w);
+ fprintf(stderr, "cycle: last edge %lx %s(%lx) %s(%lx)\n",
+ (unsigned long int)e,
+ n->name,
+ (unsigned long int)n,
+ w->name,
+ (unsigned long int)w);
return w;
}
else {
if (ND_mark(w) == FALSE) {
x = checkdfs(w);
if (x) {
- fprintf(stderr,"unwind %x %s(%x)\n",e,n->name,n);
+ fprintf(stderr,"unwind %lx %s(%lx)\n",
+ (unsigned long int)e,
+ n->name,
+ (unsigned long int)n);
if (x != n) return x;
fprintf(stderr,"unwound to root\n");
fflush(stderr);
static void printpt(FILE * f, point pt)
{
- fprintf(f, " %.3f %.3f", PS2INCH(pt.x), PS2INCH(YDIR(pt.y)));
+ fprintf(f, " %.3g %.3g", PS2INCH(pt.x), PS2INCH(YDIR(pt.y)));
}
-#ifdef SPLINESF
static void printptf(FILE * f, pointf pt)
{
- fprintf(f, " %.3f %.3f", PS2INCH(pt.x), PS2INCH(YDIR(pt.y)));
+ fprintf(f, " %.3g %.3g", PS2INCH(pt.x), PS2INCH(YDIR(pt.y)));
}
-#endif
/* setYInvert:
* Set parameters used to flip coordinate system (y=0 at top).
// setup_graph(job, g);
setYInvert(g);
pt = GD_bb(g).UR;
- fprintf(f, "graph %.3f %.3f %.3f\n", job->zoom, PS2INCH(pt.x), PS2INCH(pt.y));
+ fprintf(f, "graph %.3g %.3g %.3g\n", job->zoom, PS2INCH(pt.x), PS2INCH(pt.y));
for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
if (IS_CLUST_NODE(n))
continue;
lbl = agcanonical (agxget(n, N_label->index));
else
lbl = agcanon(ND_label(n)->text);
- fprintf(f, " %.3f %.3f %s %s %s %s %s\n",
+ fprintf(f, " %.3g %.3g %s %s %s %s %s\n",
ND_width(n), ND_height(n), lbl,
late_nnstring(n, N_style, "solid"),
ND_shape(n)->name,
}
if (ED_label(e)) {
fprintf(f, " %s", agcanon(ED_label(e)->text));
- printpt(f, ED_label(e)->p);
+ printptf(f, ED_label(e)->pos);
}
fprintf(f, " %s %s\n", late_nnstring(e, E_style, "solid"),
late_nnstring(e, E_color, DEFAULT_COLOR));
char buf[BUFSIZ];
if (f->n_flds == 0) {
- sprintf(buf, "%d,%d,%d,%d ",
- f->b.LL.x + ND_coord_i(n).x,
- YDIR(f->b.LL.y + ND_coord_i(n).y),
- f->b.UR.x + ND_coord_i(n).x,
- YDIR(f->b.UR.y + ND_coord_i(n).y));
+ sprintf(buf, "%.3g,%.3g,%.3g,%.3g ",
+ f->b.LL.x + (double)(ND_coord_i(n).x),
+ YFDIR(f->b.LL.y + (double)(ND_coord_i(n).y)),
+ f->b.UR.x + (double)(ND_coord_i(n).x),
+ YFDIR(f->b.UR.y + (double)(ND_coord_i(n).y)));
agxbput(xb, buf);
}
for (i = 0; i < f->n_flds; i++)
{
int c;
char buf[BUFSIZ];
- point pt;
+ 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));
agset(g, "bb", buf);
if (GD_label(g) && GD_label(g)->text[0]) {
- pt = GD_label(g)->p;
- sprintf(buf, "%d,%d", pt.x, YDIR(pt.y));
+ pt = GD_label(g)->pos;
+ sprintf(buf, "%.3g,%.3g", pt.x, YFDIR(pt.y));
agset(g, "lp", buf);
}
for (c = 1; c <= GD_n_cluster(g); c++)
node_t *n;
edge_t *e;
point pt;
-#ifdef SPLINESF
- point ptf;
-#endif
+ pointf ptf;
int dim3 = (GD_odim(g) >= 3);
e_arrows = s_arrows = 0;
if (GD_label(g)) {
safe_dcl(g, g, "lp", "", agraphattr);
if (GD_label(g)->text[0]) {
- pt = GD_label(g)->p;
- sprintf(buf, "%d,%d", pt.x, YDIR(pt.y));
+ ptf = GD_label(g)->pos;
+ sprintf(buf, "%.3g,%.3g", ptf.x, YFDIR(ptf.y));
agset(g, "lp", buf);
}
}
if (i > 0)
agxbputc(&xb, ' ');
if (poly->sides >= 3)
- sprintf(buf, "%.3f %.3f",
+ sprintf(buf, "%.3g %.3g",
PS2INCH(poly->vertices[i].x),
YFDIR(PS2INCH(poly->vertices[i].y)));
else
- sprintf(buf, "%.3f %.3f",
+ sprintf(buf, "%.3g %.3g",
ND_width(n) / 2.0 * cos(i /
(double) sides *
M_PI * 2.0),
if (ED_spl(e)->list[i].sflag) {
s_arrows = 1;
#ifdef SPLINESF
- sprintf(buf, "s,%.3f,%.3f ",
+ sprintf(buf, "s,%.3g,%.3g ",
ED_spl(e)->list[i].sp.x,
YFDIR(ED_spl(e)->list[i].sp.y));
#else
if (ED_spl(e)->list[i].eflag) {
e_arrows = 1;
#ifdef SPLINESF
- sprintf(buf, "e,%.3f,%.3f ",
+ sprintf(buf, "e,%.3g,%.3g ",
ED_spl(e)->list[i].ep.x,
YFDIR(ED_spl(e)->list[i].ep.y));
#else
agxbputc(&xb, ' ');
#ifdef SPLINESF
ptf = ED_spl(e)->list[i].list[j];
- sprintf(buf, "%.3f,%.3f", ptf.x, YFDIR(ptf.y));
+ sprintf(buf, "%.3g,%.3g", ptf.x, YFDIR(ptf.y));
#else
pt = ED_spl(e)->list[i].list[j];
sprintf(buf, "%d,%d", pt.x, YDIR(pt.y));
}
agset(e, "pos", agxbuse(&xb));
if (ED_label(e)) {
- pt = ED_label(e)->p;
- sprintf(buf, "%d,%d", pt.x, YDIR(pt.y));
+ ptf = ED_label(e)->pos;
+ sprintf(buf, "%.3g,%.3g", ptf.x, YFDIR(ptf.y));
agset(e, "lp", buf);
}
if (ED_head_label(e)) {
- pt = ED_head_label(e)->p;
- sprintf(buf, "%d,%d", pt.x, YDIR(pt.y));
+ ptf = ED_head_label(e)->pos;
+ sprintf(buf, "%.3g,%.3g", ptf.x, YFDIR(ptf.y));
agset(e, "head_lp", buf);
}
if (ED_tail_label(e)) {
- pt = ED_tail_label(e)->p;
- sprintf(buf, "%d,%d", pt.x, YDIR(pt.y));
+ ptf = ED_tail_label(e)->pos;
+ sprintf(buf, "%.3g,%.3g", ptf.x, YDIR(ptf.y));
agset(e, "tail_lp", buf);
}
}
closepath stroke\n\
} def\n"
-#ifdef SPLINESF
static pointf map_pointf(pointf p)
{
p = ccwrotatepf(p, Rankdir*90);
p.y -= (double)Offset.y;
return p;
}
-#endif
static point map_point(point p)
{
#endif
}
if (ED_label(e))
- ED_label(e)->p = map_point(ED_label(e)->p);
+ ED_label(e)->pos = map_pointf(ED_label(e)->pos);
/* vladimir */
if (ED_head_label(e))
- ED_head_label(e)->p = map_point(ED_head_label(e)->p);
+ ED_head_label(e)->pos = map_pointf(ED_head_label(e)->pos);
if (ED_tail_label(e))
- ED_tail_label(e)->p = map_point(ED_tail_label(e)->p);
+ ED_tail_label(e)->pos = map_pointf(ED_tail_label(e)->pos);
}
void translate_bb(graph_t * g, int rankdir)
}
GD_bb(g) = new_bb;
if (GD_label(g)) {
- GD_label(g)->p = map_point(GD_label(g)->p);
+ GD_label(g)->pos = map_pointf(GD_label(g)->pos);
}
for (c = 1; c <= GD_n_cluster(g); c++)
translate_bb(GD_clust(g)[c], rankdir);
p.y = GD_bb(g).LL.y + d.y / 2;
}
- GD_label(g)->p = p;
+ P2PF(p, GD_label(g)->pos);
GD_label(g)->set = TRUE;
}
#endif
}
- GD_label(g)->p = p;
+ P2PF(p, GD_label(g)->pos);
GD_label(g)->set = TRUE;
}
GD_bb(g->root).LL.x = minx;
#endif
}
- GD_label(g)->p = p;
+ P2PF(p, GD_label(g)->pos);
GD_label(g)->set = TRUE;
}
extern void emit_label(GVJ_t * job, emit_state_t emit_state, textlabel_t *);
extern int emit_once(char *message);
extern void emit_jobs_eof(GVC_t * gvc);
- extern void emit_map_rect(GVJ_t *job, point LL, point UR);
+ extern void emit_map_rect(GVJ_t *job, boxf b);
extern void enqueue_neighbors(nodequeue *, Agnode_t *, int);
extern void endpath(path *, Agedge_t *, int, pathend_t *, boolean);
extern void epsf_init(node_t * n);
double angle, sinx, cosx, xmax, ymax, scalex, scaley;
double width, height, marginx, marginy;
int regular, peripheries, sides;
- int i, j, isBox, outp, labelloc;
+ int i, j, isBox, outp;
polygon_t *poly = NEW(polygon_t);
regular = ND_shape(n)->polygon->regular;
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)) {
/* padding */
if ((p = agget(n, "margin"))) {
/* extra sizing depends on if label is centered vertically */
p = agget(n, "labelloc");
- if (p && p[0] == 't')
- labelloc = +1;
- else if (p && p[0] == 'b')
- labelloc = -1;
- else
- labelloc = 0;
+ if (p && (p[0] == 't' || p[0] == 'b'))
+ ND_label(n)->valign = p[0];
+ else
+ ND_label(n)->valign = 'c';
isBox = (sides == 4 && (ROUND(orientation) % 90) == 0
&& distortion == 0. && skew == 0.);
*/
temp = bb.y * SQRT2;
/* if there is height to spare and the label is centered vertically */
- if (height > temp && labelloc == 0) {
+ if (height > temp && ND_label(n)->valign == 'c') {
bb.x *= sqrt(1. / (1. - SQR(bb.y / height)));
bb.y = height;
}
bb.x = bb.y = MAX(bb.x, bb.y);
}
- /* adjust text horizontal justification
- * If ND_label(n)->d.x is set, it specifies how far from the
- * center are the x positions for left or right justification.
- * For simple boxes, this is just half bb.x;
- * for other shapes, we calculate where the rectangle dimen
- * when shifted to the right, first touches the ellipse enclosed in bb.
- * In both cases, we also subtract the horizontal margin about the text.
- */
+ /* Compute space available for label. Provides the justification borders */
if (!mapbool(late_string(n, N_nojustify, "false"))) {
if (isBox)
temp = bb.x;
else
temp = bb.x*sqrt(1.0 - SQR(dimen.y)/SQR(bb.y));
- temp = (temp - (dimen.x - ND_label(n)->dimen.x))/2.0;
-#if 0
- if (dimen.x < imagesize.x)
- temp += imagesize.x - dimen.x;
-#endif
- if (temp > 0)
- ND_label(n)->d.x = temp;
+ ND_label(n)->space.x = temp;
}
+ else
+ ND_label(n)->space.x = dimen.x;
- /* adjust text vertical location */
temp = bb.y - min_bb.y;
if (dimen.y < imagesize.y)
temp += imagesize.y - dimen.y;
- if (temp > 0) {
- if (labelloc < 0)
- ND_label(n)->d.y = -temp;
- else if (labelloc > 0)
- ND_label(n)->d.y = temp;
- else
- ND_label(n)->d.y = 0;
- }
+ ND_label(n)->space.y = dimen.y + temp;
outp = peripheries;
if (peripheries < 1)
int i, i1, j, s;
pointf P, Q, R;
- box *bp = inside_context->s.bp;
+ boxf *bp = inside_context->s.bp;
node_t *n = inside_context->s.n;
P = ccwrotatepf(p, 90*GD_rankdir(n->graph));
/* Quick test if port rectangle is target */
if (bp) {
- box bbox = *bp;
+ boxf bbox = *bp;
return INSIDE(P, bbox);
}
* return it.
* Assumes ictxt and ictxt->n are non-NULL.
*/
-static point
+static pointf
compassPoint(inside_t* ictxt, double y, double x)
{
- point p;
pointf curve[4]; /* bezier control points for a straight line */
node_t* n = ictxt->s.n;
bezier_clip(ictxt, ND_shape(n)->fns->insidefn, curve, 1);
- p.x = ROUND(curve[0].x);
- p.y = ROUND(curve[0].y);
-
- return p;
+ return curve[0];
}
/* compassPort:
* symmetric, left-right symmetric, and convex.
*/
static int
-compassPort(node_t* n, box* bp, port* pp, char* compass, int sides, inside_t* ictxt)
+compassPort(node_t* n, boxf* bp, port* pp, char* compass, int sides, inside_t* ictxt)
{
- box b;
- point p, ctr;
+ boxf b;
+ pointf p, ctr;
int rv = 0;
double theta = 0.0;
boolean constrain = FALSE;
if (bp) {
b = *bp;
- p = pointof((b.LL.x + b.UR.x) / 2, (b.LL.y + b.UR.y) / 2);
+ p = pointfof((b.LL.x + b.UR.x) / 2, (b.LL.y + b.UR.y) / 2);
defined = TRUE;
} else {
- p.x = p.y = 0;
+ p.x = p.y = 0.;
if (GD_flip(n->graph)) {
- b.UR.x = ND_ht_i(n) / 2;
+ b.UR.x = ND_ht_i(n) / 2.;
b.LL.x = -b.UR.x;
b.UR.y = ND_lw_i(n);
b.LL.y = -b.UR.y;
} else {
- b.UR.y = ND_ht_i(n) / 2;
+ b.UR.y = ND_ht_i(n) / 2.;
b.LL.y = -b.UR.y;
b.UR.x = ND_lw_i(n);
b.LL.x = -b.UR.x;
break;
}
}
- p = cwrotatep(p, 90*GD_rankdir(n->graph));
+ p = cwrotatepf(p, 90*GD_rankdir(n->graph));
if (dyna) pp->side = side;
else pp->side = invflip_side(side, GD_rankdir(n->graph));
pp->bp = bp;
- pp->p = p;
+ PF2P(p, pp->p);
pp->theta = invflip_angle(theta, GD_rankdir(n->graph));
if ((p.x == 0) && (p.y == 0))
pp->order = MC_SCALE/2;
static port poly_port(node_t * n, char *portname, char *compass)
{
port rv;
- box *bp;
+ boxf *bp;
int sides; /* bitmap of which sides the port lies along */
if (portname[0] == '\0')
AF = ALLOC(A_size, AF, pointf);
}
- ND_label(n)->p = ND_coord_i(n);
+ /* nominal label position in the center of the node */
+ P2PF(ND_coord_i(n), ND_label(n)->pos);
+
xsize = (double)(ND_lw_i(n) + ND_rw_i(n)) / POINTS(ND_width(n));
ysize = (double)ND_ht_i(n) / POINTS(ND_height(n));
{
int i, amt;
double inc;
- point d, newsz;
+ pointf d;
+ point newsz;
field_t *sf;
/* adjust field */
d.y = sz.y - f->size.y;
f->size = sz;
- /* adjust text */
+ /* adjust text area */
if (f->lp && !nojustify_p) {
- P2PF(d, f->lp->d);
+ f->lp->space.x += d.x;
+ f->lp->space.y += d.y;
}
/* adjust children */
if (f->n_flds) {
if (f->LR)
- inc = (double) d.x / f->n_flds;
+ inc = d.x / f->n_flds;
else
- inc = (double) d.y / f->n_flds;
+ inc = d.y / f->n_flds;
for (i = 0; i < f->n_flds; i++) {
sf = f->fld[i];
amt = ((int) ((i + 1) * inc)) - ((int) (i * inc));
int i, last, mask;
f->sides = sides;
- f->b.LL = pointof(ul.x, ul.y - f->size.y);
- f->b.UR = pointof(ul.x + f->size.x, ul.y);
+ f->b.LL = pointfof(ul.x, ul.y - f->size.y);
+ f->b.UR = pointfof(ul.x + f->size.x, ul.y);
last = f->n_flds - 1;
for (i = 0; i <= last; i++) {
if (sides) {
"node %s, port %s, unrecognized compass point '%s' - ignored\n",
n->name, portname, compass);
}
- } else if (compassPort(n, &f->b, &rv, portname, sides, NULL)) {
+ }
+ else if (compassPort(n, &f->b, &rv, portname, sides, NULL)) {
unrecognized(n, portname);
}
{
field_t *fld0;
- box *bp = inside_context->s.bp;
+ boxf *bp = inside_context->s.bp;
node_t *n = inside_context->s.n;
- box bbox;
+ boxf bbox;
/* convert point to node coordinate system */
p = ccwrotatepf(p, 90*GD_rankdir(n->graph));
int i, ls, rs;
point p;
field_t *info;
+ box B;
if (!prt->defined) return 0;
p = prt->p;
if (BETWEEN(ls, p.x, rs)) {
/* FIXME: I don't understand this code */
if (GD_flip(n->graph)) {
- rv[0] = flip_rec_box(info->fld[i]->b, ND_coord_i(n));
+ BF2B(info->fld[i]->b, B);
+ rv[0] = flip_rec_box(B, ND_coord_i(n));
} else {
rv[0].LL.x = ND_coord_i(n).x + ls;
- rv[0].LL.y = ND_coord_i(n).y - ND_ht_i(n) / 2;
+ rv[0].LL.y = ND_coord_i(n).y - ND_ht_i(n) / 2.;
rv[0].UR.x = ND_coord_i(n).x + rs;
}
rv[0].UR.y = ND_coord_i(n).y + ND_ht_i(n) / 2;
static void gen_fields(GVJ_t * job, node_t * n, field_t * f)
{
int i;
- double cx, cy;
pointf AF[2], coord;
if (f->lp) {
- cx = (f->b.LL.x + f->b.UR.x) / 2.0 + ND_coord_i(n).x;
- cy = (f->b.LL.y + f->b.UR.y) / 2.0 + ND_coord_i(n).y;
- f->lp->p = pointof((int) cx, (int) cy);
+ coord.x = (f->b.LL.x + f->b.UR.x) / 2.0 + ND_coord_i(n).x;
+ coord.y = (f->b.LL.y + f->b.UR.y) / 2.0 + ND_coord_i(n).y;
+ f->lp->pos = coord;
emit_label(job, EMIT_NLABEL, f->lp);
pencolor(job, n);
}
"%d %d translate newpath user_shape_%d\n",
ND_coord_i(n).x + desc->offset.x,
ND_coord_i(n).y + desc->offset.y, desc->macro_id);
- ND_label(n)->p = ND_coord_i(n);
+ P2PF(ND_coord_i(n), ND_label(n)->pos);
gvrender_end_context(job);
emit_label(job, EMIT_NLABEL, ND_label(n));
static point
cvtPt (point p, int rankdir)
{
- point q;
+ point q = {0, 0};
switch (rankdir) {
case RANKDIR_TB :
static char* closestSide (node_t* n, node_t* other, port* oldport)
{
- box b;
+ boxf b;
int rkd = GD_rankdir(n->graph->root);
- point p, pt = cvtPt (ND_coord_i(n), rkd);
+ point p = {0, 0};
+ point pt = cvtPt (ND_coord_i(n), rkd);
point opt = cvtPt (ND_coord_i(other), rkd);
int sides = oldport->side;
char* rv = NULL;
- int i, d, mind;
+ int i, d, mind = 0;
if (sides == 0) return rv; /* use center */
int start, end, i, clipTail, clipHead;
graph_t *g;
edge_t *orig;
- box *tbox, *hbox;
- boxf bb;
+ boxf *tbox, *hbox, bb;
inside_t inside_context;
tn = fe->tail;
width = ED_label(e)->dimen.x;
height = ED_label(e)->dimen.y;
}
- ED_label(e)->p.y = ND_coord_i(n).y - dy - height / 2.0;
- ED_label(e)->p.x = ND_coord_i(n).x;
+ ED_label(e)->pos.y = ND_coord_i(n).y - dy - height / 2.0;
+ ED_label(e)->pos.x = ND_coord_i(n).x;
ED_label(e)->set = TRUE;
if (height > stepy)
dy += height - stepy;
width = ED_label(e)->dimen.x;
height = ED_label(e)->dimen.y;
}
- ED_label(e)->p.y = ND_coord_i(n).y + dy + height / 2.0;
- ED_label(e)->p.x = ND_coord_i(n).x;
+ ED_label(e)->pos.y = ND_coord_i(n).y + dy + height / 2.0;
+ ED_label(e)->pos.x = ND_coord_i(n).x;
ED_label(e)->set = TRUE;
if (height > stepy)
dy += height - stepy;
width = ED_label(e)->dimen.x;
height = ED_label(e)->dimen.y;
}
- ED_label(e)->p.x = ND_coord_i(n).x + dx + width / 2.0;
- ED_label(e)->p.y = ND_coord_i(n).y;
+ ED_label(e)->pos.x = ND_coord_i(n).x + dx + width / 2.0;
+ ED_label(e)->pos.y = ND_coord_i(n).y;
ED_label(e)->set = TRUE;
if (width > stepx)
dx += width - stepx;
width = ED_label(e)->dimen.x;
height = ED_label(e)->dimen.y;
}
- ED_label(e)->p.x = ND_coord_i(n).x - dx - width / 2.0;
- ED_label(e)->p.y = ND_coord_i(n).y;
+ ED_label(e)->pos.x = ND_coord_i(n).x - dx - width / 2.0;
+ ED_label(e)->pos.y = ND_coord_i(n).y;
ED_label(e)->set = TRUE;
if (width > stepx)
dx += width - stepx;
angle = atan2(pf.y - p.y, pf.x - p.x) +
RADIANS(late_double(e, E_labelangle, PORT_LABEL_ANGLE, -180.0));
dist = PORT_LABEL_DISTANCE * late_double(e, E_labeldistance, 1.0, 0.0);
- l->p.x = p.x + ROUND(dist * cos(angle));
- l->p.y = p.y + ROUND(dist * sin(angle));
+ l->pos.x = p.x + dist * cos(angle);
+ l->pos.y = p.y + dist * sin(angle);
l->set = TRUE;
}