Example #1
0
/* setYInvert:
 * Set parameters used to flip coordinate system (y=0 at top).
 * Values do not need to be unset, since if Y_invert is set, it's
 * set for * all graphs during current run, so each will 
 * reinitialize the values for its bbox.
 */
static void setYInvert(graph_t * g)
{
    if (Y_invert) {
	Y_off = GD_bb(g).UR.y + GD_bb(g).LL.y;
	YF_off = PS2INCH(Y_off);
    }
}
Example #2
0
static void init1_gd(GVC_t * gvc, graph_t * g, box bb, point pb)
{
    Dpi = GD_drawing(g)->dpi;
    if (Dpi < 1.0)
        Dpi = DEFAULT_DPI;
    DevScale = Dpi / POINTS_PER_INCH;

    Viewport.x = gvc->job->width;
    Viewport.y = gvc->job->height;
#if 0
    if (Viewport.x) {
        Zoom = gvc->job->zoom;
        GraphFocus = gvc->job->focus;
    } else {
        Viewport.x =
            (bb.UR.x - bb.LL.x + 2 * GD_drawing(g)->margin.x) * DevScale + 2;
        Viewport.y =
            (bb.UR.y - bb.LL.y + 2 * GD_drawing(g)->margin.y) * DevScale + 2;
        GraphFocus.x = (GD_bb(g).UR.x - GD_bb(g).LL.x) / 2.;
        GraphFocus.y = (GD_bb(g).UR.y - GD_bb(g).LL.y) / 2.;
        Zoom = 1.0;
    }
#else
    Zoom = gvc->job->zoom;
    GraphFocus = gvc->job->focus;
#endif
    CompScale = Zoom * DevScale;
}
Example #3
0
/* gvLayout:
 * Selects layout based on engine and binds it to gvc;
 * does the layout and sets the graph's bbox.
 * Return 0 on success.
 */
int gvLayout(GVC_t *gvc, graph_t *g, const char *engine)
{
    char buf[256];
    int rc;

    rc = gvlayout_select(gvc, engine);
    if (rc == NO_SUPPORT) {
        agerr (AGERR, "Layout type: \"%s\" not recognized. Use one of:%s\n",
                engine, gvplugin_list(gvc, API_layout, engine));
        return -1;
    }

    if (gvLayoutJobs(gvc, g) == -1)
	return -1;

/* set bb attribute for basic layout.
 * doesn't yet include margins, scaling or page sizes because
 * those depend on the renderer being used. */
    if (GD_drawing(g)->landscape)
        sprintf(buf, "%d %d %d %d",
                ROUND(GD_bb(g).LL.y), ROUND(GD_bb(g).LL.x),
                ROUND(GD_bb(g).UR.y), ROUND(GD_bb(g).UR.x));
    else
        sprintf(buf, "%d %d %d %d",
                ROUND(GD_bb(g).LL.x), ROUND(GD_bb(g).LL.y),
                ROUND(GD_bb(g).UR.x), ROUND(GD_bb(g).UR.y));
    agsafeset(g, "bb", buf, "");

    return 0;
}
Example #4
0
static void gd_begin_graph(graph_t* g, box bb, point pb)
{
	Viewport = GD_drawing(g)->viewport.size;
	if (Viewport.x) {
		GraphFocus = GD_drawing(g)->viewport.focus;
		Zoom = GD_drawing(g)->viewport.zoom;
	}
	else {
		Viewport.x = (bb.UR.x - bb.LL.x + 2*GD_drawing(g)->margin.x) * SCALE + 1;
		Viewport.y = (bb.UR.y - bb.LL.y + 2*GD_drawing(g)->margin.y) * SCALE + 1;
		GraphFocus.x = (GD_bb(g).UR.x - GD_bb(g).LL.x) / 2.;
		GraphFocus.y = (GD_bb(g).UR.y - GD_bb(g).LL.y) / 2.;
		Zoom = SCALE;
	}
}
Example #5
0
void QGVSubGraph::updateLayout()
{
    prepareGeometryChange();

    //SubGraph box
		boxf box = GD_bb(_sgraph->graph());
    pointf p1 = box.UR;
    pointf p2 = box.LL;
    _width = p1.x - p2.x;
    _height = p1.y - p2.y;

		qreal gheight = QGVCore::graphHeight(_scene->_graph->graph());
    setPos(p2.x, gheight - p1.y);

    _pen.setWidth(1);
    _brush.setStyle(QGVCore::toBrushStyle(getAttribute("style")));
    _brush.setColor(QGVCore::toColor(getAttribute("fillcolor")));
    _pen.setColor(QGVCore::toColor(getAttribute("color")));

    //SubGraph label
		textlabel_t *xlabel = GD_label(_sgraph->graph());
    if(xlabel)
    {
        _label = xlabel->text;
        _label_rect.setSize(QSize(xlabel->dimen.x, xlabel->dimen.y));
				_label_rect.moveCenter(QGVCore::toPoint(xlabel->pos, QGVCore::graphHeight(_scene->_graph->graph())) - pos());
    }
}
Example #6
0
/** Get position of a state in the graph.
 * @param state_name name of state to get position of
 * @param px upon successful return contains X position value
 * @param py upon succesful return contains Y position value
 * Positions px/py are decimal percentages of
 * graph width/height from left/top. 
 * @return true if node has been found and px/py have been set, false otherwise
 */
bool
SkillGuiGraphDrawingArea::get_state_position(std::string state_name,
					     double &px, double &py)
{
  if (! __graph) {
    return false;
  }

  for (node_t *n = agfstnode(__graph); n; n = agnxtnode(__graph, n)) {
    const char *name = agnameof(n);
    pointf nodepos = ND_coord(n);

    if (state_name == name) {
      boxf bb = GD_bb(__graph);
      double bb_width  = bb.UR.x - bb.LL.x;
      double bb_height = bb.UR.y - bb.LL.y;

      px =       nodepos.x / bb_width;
      py = 1. - (nodepos.y / bb_height);

      return true;
    }
  }

  return false;
}
Example #7
0
static void rec_attach_bb(graph_t * g)
{
    int c;
    char buf[BUFSIZ];
    point pt;

    sprintf(buf, "%d,%d,%d,%d", GD_bb(g).LL.x, GD_bb(g).LL.y,
	    GD_bb(g).UR.x, 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));
	agset(g, "lp", buf);
    }
    for (c = 1; c <= GD_n_cluster(g); c++)
	rec_attach_bb(GD_clust(g)[c]);
}
Example #8
0
void translate_bb(graph_t * g, int rankdir)
{
    int c;
    boxf bb, new_bb;

    bb = GD_bb(g);
    if (rankdir == RANKDIR_LR || rankdir == RANKDIR_BT) {
	new_bb.LL = map_point(pointfof(bb.LL.x, bb.UR.y));
	new_bb.UR = map_point(pointfof(bb.UR.x, bb.LL.y));
    } else {
	new_bb.LL = map_point(pointfof(bb.LL.x, bb.LL.y));
	new_bb.UR = map_point(pointfof(bb.UR.x, bb.UR.y));
    }
    GD_bb(g) = new_bb;
    if (GD_label(g)) {
	GD_label(g)->pos = map_point(GD_label(g)->pos);
    }
    for (c = 1; c <= GD_n_cluster(g); c++)
	translate_bb(GD_clust(g)[c], rankdir);
}
Example #9
0
/* place_graph_label:
 * Put cluster labels recursively in the non-flip case.
 * The adjustments to the bounding boxes should no longer
 * be necessary, since we now guarantee the label fits in
 * the cluster.
 */
void place_graph_label(graph_t * g)
{
    int c;
    pointf p, d;

    if ((g != agroot(g)) && (GD_label(g)) && !GD_label(g)->set) {
	if (GD_label_pos(g) & LABEL_AT_TOP) {
	    d = GD_border(g)[TOP_IX];
	    p.y = GD_bb(g).UR.y - d.y / 2;
	} else {
	    d = GD_border(g)[BOTTOM_IX];
	    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;
	} else if (GD_label_pos(g) & LABEL_AT_LEFT) {
	    p.x = GD_bb(g).LL.x + d.x / 2;
	} else {
	    p.x = (GD_bb(g).LL.x + GD_bb(g).UR.x) / 2;
	}
	GD_label(g)->pos = p;
	GD_label(g)->set = TRUE;
    }

    for (c = 1; c <= GD_n_cluster(g); c++)
	place_graph_label(GD_clust(g)[c]);
}
Example #10
0
static void rec_attach_bb(graph_t * g, Agsym_t* bbsym)
{
    int c;
    char buf[BUFSIZ];
    pointf pt;

    sprintf(buf, "%.5g,%.5g,%.5g,%.5g", GD_bb(g).LL.x, YDIR(GD_bb(g).LL.y),
	    GD_bb(g).UR.x, YDIR(GD_bb(g).UR.y));
    agxset(g, bbsym, buf);
    if (GD_label(g) && GD_label(g)->text[0]) {
	pt = GD_label(g)->pos;
	sprintf(buf, "%.5g,%.5g", pt.x, YDIR(pt.y));
	agset(g, "lp", buf);
	pt = GD_label(g)->dimen;
	sprintf(buf, "%.2f", PS2INCH(pt.x));
	agset (g, "lwidth", buf);
	sprintf(buf, "%.2f", PS2INCH(pt.y));
	agset (g, "lheight", buf);
    }
    for (c = 1; c <= GD_n_cluster(g); c++)
	rec_attach_bb(GD_clust(g)[c], bbsym);
}
static pointf get_centroid(Agraph_t *g)
{
    int     cnt = 0;
    static pointf   sum = {0.0, 0.0};
    static Agraph_t *save;
    Agnode_t *n;

    sum.x = (GD_bb(g).LL.x + GD_bb(g).UR.x) / 2.0;
    sum.y = (GD_bb(g).LL.y + GD_bb(g).UR.y) / 2.0;
    return sum;

    if (save == g) return sum;
    save = g;
    for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
        sum.x += ND_pos(n)[0];
        sum.y += ND_pos(n)[1];
        cnt++;
    }
    sum.x = sum.x / cnt;
    sum.y = sum.y / cnt;
    return sum;
}
Example #12
0
void tcldot_layout(GVC_t *gvc, Agraph_t * g, char *engine)
{
    char buf[256];
    Agsym_t *a;
    int rc;

    gvFreeLayout(gvc, g);               /* in case previously drawn */

/* support old behaviors if engine isn't specified*/
    if (!engine || *engine == '\0') {
	if (agisdirected(g))
	    rc = gvlayout_select(gvc, "dot");
	else
	    rc = gvlayout_select(gvc, "neato");
    }
    else {
	if (strcasecmp(engine, "nop") == 0) {
	    Nop = 2;
	    PSinputscale = POINTS_PER_INCH;
	    rc = gvlayout_select(gvc, "neato");
	}
	else {
	    rc = gvlayout_select(gvc, engine);
	}
	if (rc == NO_SUPPORT)
	    rc = gvlayout_select(gvc, "dot");
    }
    if (rc == NO_SUPPORT) {
        fprintf(stderr, "Layout type: \"%s\" not recognized. Use one of:%s\n",
                engine, gvplugin_list(gvc, API_layout, engine));
        return;
    }
    gvLayoutJobs(gvc, g);

/* set bb attribute for basic layout.
 * doesn't yet include margins, scaling or page sizes because
 * those depend on the renderer being used. */
    if (GD_drawing(g)->landscape)
	sprintf(buf, "%d %d %d %d",
		ROUND(GD_bb(g).LL.y), ROUND(GD_bb(g).LL.x),
		ROUND(GD_bb(g).UR.y), ROUND(GD_bb(g).UR.x));
    else
	sprintf(buf, "%d %d %d %d",
		ROUND(GD_bb(g).LL.x), ROUND(GD_bb(g).LL.y),
		ROUND(GD_bb(g).UR.x), ROUND(GD_bb(g).UR.y));
    if (!(a = agattr(g, AGRAPH, "bb", NULL))) 
	a = agattr(g, AGRAPH, "bb", "");
    agxset(g, a, buf);
}
Example #13
0
// used in nineml_graphicsitems.cpp:122 or thereabouts.  This method
// is a bit bizarre; I would apply the offset in the client code to
// make this a pure position accessor.
QPointF GVNode::getGVNodePosition(QPointF offset)
{
    QPointF position;
#ifdef USE_LIBGRAPH_NOT_LIBCGRAPH
    position = QPointF((gv_node->u.coord.x), (layout->getGVGraph()->u.bb.UR.y - gv_node->u.coord.y));
#else
    position = QPointF(ND_coord(this->gv_node).x,
                               (GD_bb(this->layout->getGVGraph()).UR.y - ND_coord(this->gv_node).y));
#endif
    //DBG() << "getGVNodePosition: actual position: " << position
    //      << " for node ID " << ND_id(this->gv_node);
    position -= offset;
    return position;
}
Example #14
0
static void dumpBB(graph_t * g)
{
    boxf bb;
    box b;

    bb = BB(g);
    b = GD_bb(g);
    prIndent();
    fprintf(stderr, "  LL (%f,%f)  UR (%f,%f)\n", bb.LL.x, bb.LL.y,
	    bb.UR.x, bb.UR.y);
    prIndent();
    fprintf(stderr, "  LL (%d,%d)  UR (%d,%d)\n", b.LL.x, b.LL.y,
	    b.UR.x, b.UR.y);
}
Example #15
0
/* computeStep:
 * Compute grid step size. This is a root of the
 * quadratic equation al^2 +bl + c, where a, b and
 * c are defined below.
 */
static int computeStep(int ng, Agraph_t ** gs, int margin)
{
    double l1, l2;
    double a, b, c, d, r;
    double W, H;		/* width and height of graph, with margin */
    Agraph_t *g;
    int i;

    a = C * ng - 1;
    c = 0;
    b = 0;
    for (i = 0; i < ng; i++) {
	g = gs[i];
	W = GD_bb(g).UR.x - GD_bb(g).LL.x + 2 * margin;
	H = GD_bb(g).UR.y - GD_bb(g).LL.y + 2 * margin;
	b -= (W + H);
	c -= (W * H);
    }
    d = b * b - 4.0 * a * c;
    if (d < 0) {
	agerr(AGERR, "libpack: disc = %f ( < 0)\n", d);
	return -1;
    }
    r = sqrt(d);
    l1 = (-b + r) / (2 * a);
    l2 = (-b - r) / (2 * a);
    if (Verbose > 2) {
	fprintf(stderr, "Packing: compute grid size\n");
	fprintf(stderr, "a %f b %f c %f d %f r %f\n", a, b, c, d, r);
	fprintf(stderr, "root %d (%f) %d (%f)\n", (int) l1, l1, (int) l2,
		l2);
	fprintf(stderr, " r1 %f r2 %f\n", a * l1 * l1 + b * l1 + c,
		a * l2 * l2 + b * l2 + c);
    }

    return (int) l1;
}
Example #16
0
/* _write_plain:
 */
void write_plain(GVJ_t * job, graph_t * g, FILE * f, boolean extend)
{
    int i, j, splinePoints;
    char *tport, *hport;
    node_t *n;
    edge_t *e;
    bezier bz;
    pointf pt;
    char *lbl;
    char* fillcolor;

#ifdef WITH_CGRAPH
    putstr = g->clos->disc.io->putstr;
#endif
//    setup_graph(job, g);
    setYInvert(g);
    pt = GD_bb(g).UR;
    printdouble(f, "graph ", job->zoom);
    printdouble(f, " ", PS2INCH(pt.x));
    printdouble(f, " ", PS2INCH(pt.y));
    agputc('\n', f);
    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	if (IS_CLUST_NODE(n))
	    continue;
	printstring(f, "node ", agcanonStr(agnameof(n)));
	printpoint(f, ND_coord(n));
	if (ND_label(n)->html)   /* if html, get original text */
#ifndef WITH_CGRAPH
	    lbl = agcanonStr (agxget(n, N_label->index));
#else
	    lbl = agcanonStr (agxget(n, N_label));
#endif
	else
	    lbl = canon(agraphof(n),ND_label(n)->text);
        printdouble(f, " ", ND_width(n));
        printdouble(f, " ", ND_height(n));
        printstring(f, " ", lbl);
	printstring(f, " ", late_nnstring(n, N_style, "solid"));
	printstring(f, " ", ND_shape(n)->name);
	printstring(f, " ", late_nnstring(n, N_color, DEFAULT_COLOR));
	fillcolor = late_nnstring(n, N_fillcolor, "");
        if (fillcolor[0] == '\0')
	    fillcolor = late_nnstring(n, N_color, DEFAULT_FILL);
	printstring(f, " ", fillcolor);
	agputc('\n', f);
    }
Example #17
0
/* compute_bb:
 * Compute bounding box of g using nodes, splines, and clusters.
 * Assumes bb of clusters already computed.
 * store in GD_bb.
 */
void compute_bb(graph_t * g)
{
    node_t *n;
    edge_t *e;
    box b, bb;
    point pt, s2;
    int i, j;

    bb.LL = pointof(MAXINT, MAXINT);
    bb.UR = pointof(-MAXINT, -MAXINT);
    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);

	EXPANDBB(bb,b);
	for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
	    if (ED_spl(e) == 0)
		continue;
	    for (i = 0; i < ED_spl(e)->size; i++) {
		for (j = 0; j < ED_spl(e)->list[i].size; j++) {
		    pt = ED_spl(e)->list[i].list[j];
		    EXPANDBP(bb,pt);
		}
	    }
	    if (ED_label(e) && ED_label(e)->set)
		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);
    }

    GD_bb(g) = bb;
}
Example #18
0
QPointF GVEdge::getGVEdgeLabelPosition(QPointF offset)
{
    QPointF position(0,0);

#ifdef USE_LIBGRAPH_NOT_LIBCGRAPH
    position = QPointF(this->gv_edge->u.label->pos.x,
                       this->layout->getGVGraph()->u.bb.UR.y - this->gv_edge->u.label->pos.y);
#else
    qreal a = 0;
    qreal b = 0;
    textlabel_t* edgelabel = ED_label(this->gv_edge);
    if (edgelabel != NULL) {
        a = edgelabel->pos.x;
    } else {
        DBG() << "Warning: edge label doesn't exist in this->gv_edge...";
    }
    //char* l = agget (this->gv_edge, (char*)"label");
    b = (GD_bb(this->layout->getGVGraph()).UR.y - ED_label(this->gv_edge)->pos.y);
    position = QPointF(a,b);
#endif

    position -= offset;
    return position;
}
Example #19
0
/* place_root_label:
 * Set position of root graph label.
 * Note that at this point, after translate_drawing, a
 * 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, pointf d)
{
    pointf p;

    if (GD_label_pos(g) & LABEL_AT_RIGHT) {
	p.x = GD_bb(g).UR.x - d.x / 2;
    } else if (GD_label_pos(g) & LABEL_AT_LEFT) {
	p.x = GD_bb(g).LL.x + d.x / 2;
    } else {
	p.x = (GD_bb(g).LL.x + GD_bb(g).UR.x) / 2;
    }

    if (GD_label_pos(g) & LABEL_AT_TOP) {
	p.y = GD_bb(g).UR.y - d.y / 2;
    } else {
	p.y = GD_bb(g).LL.y + d.y / 2;
    }

    GD_label(g)->pos = p;
    GD_label(g)->set = TRUE;
}
Example #20
0
/* updateBB:
 * Reset graph's bounding box to include bounding box of the given label.
 * Assume the label's position has been set.
 */
void updateBB(graph_t * g, textlabel_t * lp)
{
    GD_bb(g) = addLabelBB(GD_bb(g), lp, GD_flip(g));
}
Example #21
0
/* dotneato_postprocess:
 * Set graph and cluster label positions.
 * Add space for root graph label and translate graph accordingly.
 * Set final nodesize using ns.
 * Assumes the boxes of all clusters have been computed.
 * When done, the bounding box of g has LL at origin.
 */
void dotneato_postprocess(Agraph_t * g)
{
    int diff;
    pointf dimen;
    point d = { 0, 0 };

    Rankdir = GD_rankdir(g);
    Flip = GD_flip(g);
    if (Flip)
	place_flip_graph_label(g);
    else
	place_graph_label(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;
	    } else {
		GD_bb(g).LL.x -= d.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;
		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;
		else
		    GD_bb(g).LL.y -= d.y;
	    } else {
		if (Rankdir == RANKDIR_TB)
		    GD_bb(g).LL.y -= d.y;
		else
		    GD_bb(g).UR.y += d.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;
		GD_bb(g).LL.x -= diff;
		GD_bb(g).UR.x += diff;
	    }
	}
    }
    switch (Rankdir) {
    case RANKDIR_TB:
	Offset = GD_bb(g).LL;
	break;
    case RANKDIR_LR:
	Offset = pointof(-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);
	break;
    case RANKDIR_RL:
	Offset = pointof(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);

    if (Show_boxes) {
	char buf[BUFSIZ];
	if (Flip)
	    sprintf(buf, M2, Offset.x, Offset.y, Offset.x, Offset.y);
	else
	    sprintf(buf, M1, Offset.y, Offset.x, Offset.y, Offset.x, 
                 -Offset.x, -Offset.y);
	Show_boxes[0] = strdup(buf);
    }
}
Example #22
0
QPointF GVEdge::getGVEdgeSplinesEndPoint()
{
    QPointF spline = QPointF(ED_spl(this->gv_edge)->list->ep.x,
                             GD_bb(this->layout->getGVGraph()).UR.y - ED_spl(this->gv_edge)->list->ep.y);
    return spline;
}
Example #23
0
/* place_flip_graph_label:
 * Put cluster labels recursively in the flip case.
 */
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

    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];
	    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];
	    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
	}

	GD_label(g)->p = p;
	GD_label(g)->set = TRUE;
    }

    for (c = 1; c <= GD_n_cluster(g); c++)
	place_flip_graph_label(GD_clust(g)[c]);
}
Example #24
0
/* place_graph_label:
 * Put cluster labels recursively in the non-flip case.
 * The adjustments to the bounding boxes should no longer
 * be necessary, since we now guarantee the label fits in
 * the cluster.
 */
void place_graph_label(graph_t * g)
{
    int c;
#ifdef OLD
    int minx, maxx;
#endif
    point 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];
	    p.y = GD_bb(g).UR.y - d.y / 2;
	} else {
	    d = GD_border(g)[BOTTOM_IX];
	    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
	}
	GD_label(g)->p = p;
	GD_label(g)->set = TRUE;
    }

    for (c = 1; c <= GD_n_cluster(g); c++)
	place_graph_label(GD_clust(g)[c]);
}
Example #25
0
/* _write_plain:
 */
void write_plain(GVJ_t * job, graph_t * g, FILE * f, boolean extend)
{
    int i, j, splinePoints;
    char *tport, *hport;
    node_t *n;
    edge_t *e;
    bezier bz;
    pointf pt;
    char *lbl;
    char* fillcolor;

    putstr = g->clos->disc.io->putstr;
//    setup_graph(job, g);
    setYInvert(g);
    pt = GD_bb(g).UR;
    printdouble(f, "graph ", job->zoom);
    printdouble(f, " ", PS2INCH(pt.x));
    printdouble(f, " ", PS2INCH(pt.y));
    agputc('\n', f);
    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	if (IS_CLUST_NODE(n))
	    continue;
	printstring(f, "node ", agcanonStr(agnameof(n)));
	printpoint(f, ND_coord(n));
	if (ND_label(n)->html)   /* if html, get original text */
	    lbl = agcanonStr (agxget(n, N_label));
	else
	    lbl = canon(agraphof(n),ND_label(n)->text);
        printdouble(f, " ", ND_width(n));
        printdouble(f, " ", ND_height(n));
        printstring(f, " ", lbl);
	printstring(f, " ", late_nnstring(n, N_style, "solid"));
	printstring(f, " ", ND_shape(n)->name);
	printstring(f, " ", late_nnstring(n, N_color, DEFAULT_COLOR));
	fillcolor = late_nnstring(n, N_fillcolor, "");
        if (fillcolor[0] == '\0')
	    fillcolor = late_nnstring(n, N_color, DEFAULT_FILL);
	printstring(f, " ", fillcolor);
	agputc('\n', f);
    }
    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	for (e = agfstout(g, n); e; e = agnxtout(g, e)) {

	    if (extend) {		//assuming these two attrs have already been created by cgraph
		if (!(tport = agget(e,"tailport")))
		    tport = "";
		if (!(hport = agget(e,"headport")))
		    hport = "";
	    }
	    else
		tport = hport = "";
	    if (ED_spl(e)) {
		splinePoints = 0;
		for (i = 0; i < ED_spl(e)->size; i++) {
		    bz = ED_spl(e)->list[i];
		    splinePoints += bz.size;
		}
		printstring(f, NULL, "edge");
		writenodeandport(f, agtail(e), tport);
		writenodeandport(f, aghead(e), hport);
		printint(f, " ", splinePoints);
		for (i = 0; i < ED_spl(e)->size; i++) {
		    bz = ED_spl(e)->list[i];
		    for (j = 0; j < bz.size; j++)
			printpoint(f, bz.list[j]);
		}
	    }
	    if (ED_label(e)) {
		printstring(f, " ", canon(agraphof(agtail(e)),ED_label(e)->text));
		printpoint(f, ED_label(e)->pos);
	    }
	    printstring(f, " ", late_nnstring(e, E_style, "solid"));
	    printstring(f, " ", late_nnstring(e, E_color, DEFAULT_COLOR));
	    agputc('\n', f);
	}
    }
    agputs("stop\n", f);
}
Example #26
0
qreal QGVCore::graphHeight(Agraph_t *graph)
{
  return GD_bb(graph).UR.y;
}
Example #27
0
/* gv_postprocess:
 * Set graph and cluster label positions.
 * Add space for root graph label and translate graph accordingly.
 * Set final nodesize using ns.
 * Assumes the boxes of all clusters have been computed.
 * When done, the bounding box of g has LL at origin.
 */
void gv_postprocess(Agraph_t * g, int allowTranslation)
{
    double diff;
    pointf dimen = { 0., 0. };


    Rankdir = GD_rankdir(g);
    Flip = GD_flip(g);
    /* Handle cluster labels */
    if (Flip)
	place_flip_graph_label(g);
    else
	place_graph_label(g);

    /* Everything has been placed except the root graph label, if any.
     * The graph positions have not yet been rotated back if necessary.
     */
    addXLabels(g);

    /* Add space for graph label if necessary */
    if (GD_label(g) && !GD_label(g)->set) {
	dimen = GD_label(g)->dimen;
	PAD(dimen);
	if (Flip) {
	    if (GD_label_pos(g) & LABEL_AT_TOP) {
		GD_bb(g).UR.x += dimen.y;
	    } else {
		GD_bb(g).LL.x -= dimen.y;
	    }

	    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 += dimen.y;
		else
		    GD_bb(g).LL.y -= dimen.y;
	    } else {
		if (Rankdir == RANKDIR_TB)
		    GD_bb(g).LL.y -= dimen.y;
		else
		    GD_bb(g).UR.y += dimen.y;
	    }

	    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;
	    }
	}
    }
    if (allowTranslation) {
	switch (Rankdir) {
	case RANKDIR_TB:
	    Offset = GD_bb(g).LL;
	    break;
	case RANKDIR_LR:
	    Offset = pointfof(-GD_bb(g).UR.y, GD_bb(g).LL.x);
	    break;
	case RANKDIR_BT:
	    Offset = pointfof(GD_bb(g).LL.x, -GD_bb(g).UR.y);
	    break;
	case RANKDIR_RL:
	    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, dimen);

    if (Show_boxes) {
	char buf[BUFSIZ];
	if (Flip)
	    sprintf(buf, M2, Offset.x, Offset.y, Offset.x, Offset.y);
	else
	    sprintf(buf, M1, Offset.y, Offset.x, Offset.y, Offset.x,
		    -Offset.x, -Offset.y);
	Show_boxes[0] = strdup(buf);
    }
}
Example #28
0
qreal QGVCore::graphHeight(Agraph_t *graph)
{
    //Hauteur totale du graphique (permet d'effectuer le calcul inverse des coordonnées)
    return GD_bb(graph).UR.y;
}
Example #29
0
/* _write_plain:
 */
void write_plain(GVJ_t * job, graph_t * g, FILE * f, bool extend)
{
    int i, j, splinePoints;
    char *tport, *hport;
    node_t *n;
    edge_t *e;
    bezier bz;
    point pt;
    char *lbl;

//    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));
    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	if (IS_CLUST_NODE(n))
	    continue;
	fprintf(f, "node %s ", agcanonical(n->name));
	printptf(f, ND_coord_i(n));
	if (ND_label(n)->html)   /* if html, get original text */
	    lbl = agxget(n, N_label->index);
	else
	    lbl = ND_label(n)->text;
	if (lbl)
	    lbl = agcanonical(lbl);
	else
	    lbl = "\"\"";
	fprintf(f, " %.3f %.3f %s %s %s %s %s\n",
		ND_width(n), ND_height(n), lbl,
		late_nnstring(n, N_style, "solid"),
		ND_shape(n)->name,
		late_nnstring(n, N_color, DEFAULT_COLOR),
		late_nnstring(n, N_fillcolor, DEFAULT_FILL));
    }
    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
	    if (extend && e->attr) {
		tport = e->attr[TAILX];
		hport = e->attr[HEADX];
	    } else
		tport = hport = "";
	    if (ED_spl(e)) {
		splinePoints = 0;
		for (i = 0; i < ED_spl(e)->size; i++) {
		    bz = ED_spl(e)->list[i];
		    splinePoints += bz.size;
		}
		fprintf(f, "edge ");
		writenodeandport(f, e->tail, tport);
		fprintf(f, " ");
		writenodeandport(f, e->head, hport);
		fprintf(f, " %d", splinePoints);
		for (i = 0; i < ED_spl(e)->size; i++) {
		    bz = ED_spl(e)->list[i];
		    for (j = 0; j < bz.size; j++)
			printptf(f, bz.list[j]);
		}
	    }
	    if (ED_label(e)) {
		fprintf(f, " %s", agcanonical(ED_label(e)->text));
		printptf(f, ED_label(e)->p);
	    }
	    fprintf(f, " %s %s\n", late_nnstring(e, E_style, "solid"),
		    late_nnstring(e, E_color, DEFAULT_COLOR));
	}
    }
    fprintf(f, "stop\n");
}
Example #30
0
static void makeCompoundEdge(graph_t * g, edge_t * e)
#endif
{
    graph_t *lh;		/* cluster containing head */
    graph_t *lt;		/* cluster containing tail */
    bezier *bez;		/* original Bezier for e */
    bezier *nbez;		/* new Bezier  for e */
    int starti = 0, endi = 0;	/* index of first and last control point */
    node_t *head;
    node_t *tail;
    boxf *bb;
    int i, j;
    int size;
    pointf pts[4];
    pointf p;
    int fixed;

    /* find head and tail target clusters, if defined */
#ifdef WITH_CGRAPH
    lh = getCluster(g, agget(e, "lhead"), clustMap);
    lt = getCluster(g, agget(e, "ltail"), clustMap);
#else
    lh = getCluster(g, agget(e, "lhead"));
    lt = getCluster(g, agget(e, "ltail"));
#endif
    if (!lt && !lh)
	return;
    if (!ED_spl(e)) return;

    /* at present, we only handle single spline case */
    if (ED_spl(e)->size > 1) {
	agerr(AGWARN, "%s -> %s: spline size > 1 not supported\n",
	      agnameof(agtail(e)), agnameof(aghead(e)));
	return;
    }
    bez = ED_spl(e)->list;
    size = bez->size;

    head = aghead(e);
    tail = agtail(e);

    /* allocate new Bezier */
    nbez = GNEW(bezier);
    nbez->eflag = bez->eflag;
    nbez->sflag = bez->sflag;

    /* if Bezier has four points, almost collinear,
     * make line - unimplemented optimization?
     */

    /* If head cluster defined, find first Bezier
     * crossing head cluster, and truncate spline to
     * box edge.
     * Otherwise, leave end alone.
     */
    fixed = 0;
    if (lh) {
	bb = &(GD_bb(lh));
	if (!inBoxf(ND_coord(head), bb)) {
	    agerr(AGWARN, "%s -> %s: head not inside head cluster %s\n",
		  agnameof(agtail(e)), agnameof(aghead(e)), agget(e, "lhead"));
	} else {
	    /* If first control point is in bb, degenerate case. Spline
	     * reduces to four points between the arrow head and the point 
	     * where the segment between the first control point and arrow head 
	     * crosses box.
	     */
	    if (inBoxf(bez->list[0], bb)) {
		if (inBoxf(ND_coord(tail), bb)) {
		    agerr(AGWARN,
			  "%s -> %s: tail is inside head cluster %s\n",
			  agnameof(agtail(e)), agnameof(aghead(e)), agget(e, "lhead"));
		} else {
		    assert(bez->sflag);	/* must be arrowhead on tail */
		    p = boxIntersectf(bez->list[0], bez->sp, bb);
		    bez->list[3] = p;
		    bez->list[1] = mid_pointf(p, bez->sp);
		    bez->list[0] = mid_pointf(bez->list[1], bez->sp);
		    bez->list[2] = mid_pointf(bez->list[1], p);
		    if (bez->eflag)
			endi = arrowEndClip(e, bez->list,
					 starti, 0, nbez, bez->eflag);
		    endi += 3;
		    fixed = 1;
		}
	    } else {
		for (endi = 0; endi < size - 1; endi += 3) {
		    if (splineIntersectf(&(bez->list[endi]), bb))
			break;
		}
		if (endi == size - 1) {	/* no intersection */
		    assert(bez->eflag);
		    nbez->ep = boxIntersectf(bez->ep, bez->list[endi], bb);
		} else {
		    if (bez->eflag)
			endi =
			    arrowEndClip(e, bez->list,
					 starti, endi, nbez, bez->eflag);
		    endi += 3;
		}
		fixed = 1;
	    }
	}
    }
    if (fixed == 0) {		/* if no lh, or something went wrong, use original head */
	endi = size - 1;
	if (bez->eflag)
	    nbez->ep = bez->ep;
    }

    /* If tail cluster defined, find last Bezier
     * crossing tail cluster, and truncate spline to
     * box edge.
     * Otherwise, leave end alone.
     */
    fixed = 0;
    if (lt) {
	bb = &(GD_bb(lt));
	if (!inBoxf(ND_coord(tail), bb)) {
	    agerr(AGWARN, "%s -> %s: tail not inside tail cluster %s\n",
		agnameof(agtail(e)), agnameof(aghead(e)), agget(e, "ltail"));
	} else {
	    /* If last control point is in bb, degenerate case. Spline
	     * reduces to four points between arrow head, and the point
	     * where the segment between the last control point and the 
	     * arrow head crosses box.
	     */
	    if (inBoxf(bez->list[endi], bb)) {
		if (inBoxf(ND_coord(head), bb)) {
		    agerr(AGWARN,
			"%s -> %s: head is inside tail cluster %s\n",
		  	agnameof(agtail(e)), agnameof(aghead(e)), agget(e, "ltail"));
		} else {
		    assert(bez->eflag);	/* must be arrowhead on head */
		    p = boxIntersectf(bez->list[endi], nbez->ep, bb);
		    starti = endi - 3;
		    bez->list[starti] = p;
		    bez->list[starti + 2] = mid_pointf(p, nbez->ep);
		    bez->list[starti + 3] = mid_pointf(bez->list[starti + 2], nbez->ep);
		    bez->list[starti + 1] = mid_pointf(bez->list[starti + 2], p);
		    if (bez->sflag)
			starti = arrowStartClip(e, bez->list, starti,
				endi - 3, nbez, bez->sflag);
		    fixed = 1;
		}
	    } else {
		for (starti = endi; starti > 0; starti -= 3) {
		    for (i = 0; i < 4; i++)
			pts[i] = bez->list[starti - i];
		    if (splineIntersectf(pts, bb)) {
			for (i = 0; i < 4; i++)
			    bez->list[starti - i] = pts[i];
			break;
		    }
		}
		if (starti == 0) {
		    assert(bez->sflag);
		    nbez->sp =
			boxIntersectf(bez->sp, bez->list[starti], bb);
		} else {
		    starti -= 3;
		    if (bez->sflag)
			starti = arrowStartClip(e, bez->list, starti,
				endi - 3, nbez, bez->sflag);
		}
		fixed = 1;
	    }
	}
    }
    if (fixed == 0) {		/* if no lt, or something went wrong, use original tail */
	/* Note: starti == 0 */
	if (bez->sflag)
	    nbez->sp = bez->sp;
    }

    /* complete Bezier, free garbage and attach new Bezier to edge 
     */
    nbez->size = endi - starti + 1;
    nbez->list = N_GNEW(nbez->size, pointf);
    for (i = 0, j = starti; i < nbez->size; i++, j++)
	nbez->list[i] = bez->list[j];
    free(bez->list);
    free(bez);
    ED_spl(e)->list = nbez;
}