_points[1] = points[1];
}
- void Ellipse::Print(GVJ_t* job, pointf first, pointf last) const
+ void Ellipse::Print(GVJ_t* job, pointf first, pointf last, bool allowCurves) const
{
gvputs(job, "<Geom>\n");
if (!_filled)
return true;
}
- void Bezier::Print(GVJ_t* job, pointf first, pointf last) const
+ void Bezier::Print(GVJ_t* job, pointf first, pointf last, bool allowCurves) const
{
gvputs(job, "<Geom>\n");
if (!_filled)
gvprintf(job, "<Y F='Height*%f' />", (_points[0].y - first.y) * yscale);
gvputs(job, "</MoveTo>\n");
- /* convert Graphviz cubic bezier into VDX NURBS curve: */
- /* NURBS control points == bezier control points */
- /* NURBS order == bezier order == 3 */
- /* NURBS knot vector == { 0, 0, 0, 0, 1, 2 ... } */
-
- gvputs(job, "<NURBSTo>");
-
- /* Ctl[P-1].X */
- gvprintf(job, "<X F='Width*%f'/>", (_points[_pointCount - 1].x - first.x) * xscale);
-
- /* Ctl[P-1].Y */
- gvprintf(job, "<Y F='Height*%f'/>", (_points[_pointCount - 1].y - first.y) * yscale);
-
- /* Knot[P-1] */
- gvprintf(job, "<A>%d</A>", std::max(_pointCount - 4, 0));
-
- /* Ctl[P-1].Weight */
- gvputs(job, "<B>1</B>");
-
- /* Knot[0] */
- gvputs(job, "<C>0</C>");
-
- /* Weight[0] */
- gvputs(job, "<D>1</D>");
-
- /* Knot[P], Degree, XType, YType */
- gvprintf(job, "<E F='NURBS(%d, 3, 0, 0", std::max(_pointCount - 3, 0));
- for (int i = 1; i < _pointCount; ++i)
- /* Ctl[i].X, Ctl[i].Y, Knot[i], Ctl[i].Weight */
- gvprintf(job, ", %f, %f, %d, 1",
- (_points[i].x - first.x) * xscale,
- (_points[i].y - first.y) * yscale,
- std::max(i - 3, 0));
- gvputs(job, ")'/>");
-
- gvputs(job, "</NURBSTo>\n");
+ if (allowCurves)
+ {
+ /* convert Graphviz cubic bezier into VDX NURBS curve: */
+ /* NURBS control points == bezier control points */
+ /* NURBS order == bezier order == 3 */
+ /* NURBS knot vector == { 0, 0, 0, 0, 1, 2 ... } */
+
+ gvputs(job, "<NURBSTo>");
+
+ /* Ctl[P-1].X */
+ gvprintf(job, "<X F='Width*%f'/>", (_points[_pointCount - 1].x - first.x) * xscale);
+
+ /* Ctl[P-1].Y */
+ gvprintf(job, "<Y F='Height*%f'/>", (_points[_pointCount - 1].y - first.y) * yscale);
+
+ /* Knot[P-1] */
+ gvprintf(job, "<A>%d</A>", std::max(_pointCount - 4, 0));
+
+ /* Ctl[P-1].Weight */
+ gvputs(job, "<B>1</B>");
+
+ /* Knot[0] */
+ gvputs(job, "<C>0</C>");
+
+ /* Weight[0] */
+ gvputs(job, "<D>1</D>");
+
+ /* Knot[P], Degree, XType, YType */
+ gvprintf(job, "<E F='NURBS(%d, 3, 0, 0", std::max(_pointCount - 3, 0));
+ for (int i = 1; i < _pointCount; ++i)
+ /* Ctl[i].X, Ctl[i].Y, Knot[i], Ctl[i].Weight */
+ gvprintf(job, ", %f, %f, %d, 1",
+ (_points[i].x - first.x) * xscale,
+ (_points[i].y - first.y) * yscale,
+ std::max(i - 3, 0));
+ gvputs(job, ")'/>");
+
+ gvputs(job, "</NURBSTo>\n");
+ }
+ else
+ {
+ /* output lines only, so skip all the Bezier control points i.e. use every 3rd point */
+
+ if (_pointCount == 4)
+ {
+ /* single point, use VDX LineTo */
+ gvputs(job, "<LineTo>");
+ gvprintf(job, "<X F='Width*%f' />", (_points[3].x - first.x) * xscale);
+ gvprintf(job, "<Y F='Height*%f' />", (_points[3].y - first.y) * yscale);
+ gvputs(job, "</LineTo>\n");
+ }
+ else
+ {
+ /* multiple points, use VDX PolylineTo */
+ gvputs(job, "<PolylineTo>");
+ gvprintf(job, "<X F='Width*%f' />", (_points[_pointCount - 1].x - first.x) * xscale);
+ gvprintf(job, "<Y F='Height*%f' />", (_points[_pointCount - 1].y - first.y) * yscale);
+ gvputs(job, "<A F='POLYLINE(0, 0");
+ for (int i = 3; i < _pointCount - 1; i += 3)
+ gvprintf(job, ", %f, %f", (_points[i].x - first.x) * xscale, (_points[i].y - first.y) * yscale);
+ gvputs(job, ")' />");
+ gvputs(job, "</PolylineTo>\n");
+ }
+ }
}
gvputs(job, "</Geom>\n");
}
return false;
}
- void Polygon::Print(GVJ_t* job, pointf first, pointf last) const
+ void Polygon::Print(GVJ_t* job, pointf first, pointf last, bool allowCurves) const
{
gvputs(job, "<Geom>\n");
if (!_filled)
return false;
}
- void Polyline::Print(GVJ_t* job, pointf first, pointf last) const
+ void Polyline::Print(GVJ_t* job, pointf first, pointf last, bool allowCurves) const
{
gvputs(job, "<Geom>\n");
if (_pointCount > 0)
return _geom->IsConnectable();
}
- void Graphic::Print(GVJ_t* job, pointf first, pointf last) const
+ void Graphic::Print(GVJ_t* job, pointf first, pointf last, bool allowCurves) const
{
if (_line)
_line->Print(job);
if (_fill)
_fill->Print(job);
if (_geom)
- _geom->Print(job, first, last);
+ _geom->Print(job, first, last, allowCurves);
}
virtual bool IsConnectable() const = 0; /* whether this geom can be turned into a connector -- used by edge logic */
/* given first (lower left) and last points (upper right), output the geometry */
- virtual void Print(GVJ_t* job, pointf first, pointf last) const = 0;
+ virtual void Print(GVJ_t* job, pointf first, pointf last, bool allowCurves) const = 0;
};
class Ellipse: public Geom
virtual pointf GetCenter() const;
virtual bool IsConnectable() const;
- void Print(GVJ_t* job, pointf first, pointf last) const;
+ void Print(GVJ_t* job, pointf first, pointf last, bool allowCurves) const;
private:
bool _filled;
virtual pointf GetCenter() const;
virtual bool IsConnectable() const;
- virtual void Print(GVJ_t* job, pointf first, pointf last) const;
+ virtual void Print(GVJ_t* job, pointf first, pointf last, bool allowCurves) const;
private:
virtual pointf GetCenter() const;
virtual bool IsConnectable() const;
- virtual void Print(GVJ_t* job, pointf first, pointf last) const;
+ virtual void Print(GVJ_t* job, pointf first, pointf last, bool allowCurves) const;
private:
bool _filled;
virtual pointf GetCenter() const;
virtual bool IsConnectable() const;
- void Print(GVJ_t* job, pointf first, pointf last) const;
+ void Print(GVJ_t* job, pointf first, pointf last, bool allowCurves) const;
};
pointf GetCenter() const;
bool IsConnectable() const;
- void Print(GVJ_t* job, pointf first, pointf last) const;
+ void Print(GVJ_t* job, pointf first, pointf last, bool allowCurves) const;
private:
Graphic(Line* line, Fill* fill, Geom* geom);
#include "VisioRender.h"
+#include "const.h"
+#include "macros.h"
#include "gvcjob.h"
#include "gvio.h"
static const float INCHES_PER_POINT = 1.0 / 72.0;
static const float ZERO_ADJUST = 0.125;
+ enum ConLineRouteExt
+ {
+ LORouteExtDefault = 0,
+ LORouteExtStraight = 1,
+ LORouteExtNURBS = 2
+ };
+
+ enum ShapeRouteStyle
+ {
+ LORouteDefault = 0,
+ LORouteRightAngle = 1,
+ LORouteStraight = 2,
+ LORouteCenterToCenter = 16
+ };
+
Render::Render():
_pageId(0),
_shapeId(0),
if (_graphics.size() > 0)
{
- /* get previously saved ids for tail and head node */
- NodeIds::const_iterator beginId = _nodeIds.find(job->obj->u.e->tail);
- NodeIds::const_iterator endId = _nodeIds.find(job->obj->u.e->head);
+ Agedge_t* edge = job->obj->u.e;
+
+ /* get previously saved ids for tail and head node; edge type for graph */
+ NodeIds::const_iterator beginId = _nodeIds.find(edge->tail);
+ NodeIds::const_iterator endId = _nodeIds.find(edge->head);
/* output first connectable shape as an edge shape, all else as regular outer shapes */
bool firstConnector = true;
for (Graphics::const_iterator nextGraphic = _graphics.begin(), lastGraphic = _graphics.end(); nextGraphic != lastGraphic; ++nextGraphic)
if (firstConnector && (*nextGraphic)->IsConnectable())
{
- PrintEdgeShape(job, _graphics[0], beginId == _nodeIds.end() ? 0 : beginId->second, endId == _nodeIds.end() ? 0 : endId->second);
+ PrintEdgeShape(job,
+ _graphics[0],
+ beginId == _nodeIds.end() ? 0 : beginId->second,
+ endId == _nodeIds.end() ? 0 : endId->second,
+ EDGE_TYPE(edge->head->graph->root));
firstConnector = false;
}
else
PrintTexts(job);
/* output Line, Fill, Geom */
- graphic->Print(job, bounds.LL, bounds.UR);
+ graphic->Print(job, bounds.LL, bounds.UR, true);
gvputs(job, "</Shape>\n");
}
gvputs(job, "</Misc>\n");
/* output Line, Fill, Geom */
- graphic->Print(job, innerBounds.LL, innerBounds.UR);
+ graphic->Print(job, innerBounds.LL, innerBounds.UR, true);
gvputs(job, "</Shape>\n");
}
- void Render::PrintEdgeShape(GVJ_t* job, Graphic* graphic, unsigned int beginId, unsigned int endId)
+ void Render::PrintEdgeShape(GVJ_t* job, Graphic* graphic, unsigned int beginId, unsigned int endId, int edgeType)
{
pointf first = graphic->GetFirst();
pointf last = graphic->GetLast();
gvputs(job, "</Misc>\n");
gvputs(job, "<Layout>\n");
- gvputs(job, "<ShapeRouteStyle>1</ShapeRouteStyle>\n");
+ gvprintf(job, "<ShapeRouteStyle>%d</ShapeRouteStyle>\n", edgeType == ET_LINE ? LORouteCenterToCenter : LORouteRightAngle);
gvputs(job, "<ConFixedCode>6</ConFixedCode>\n");
- gvputs(job, "<ConLineRouteExt>2</ConLineRouteExt>\n");
+ gvprintf(job, "<ConLineRouteExt>%d</ConLineRouteExt>\n", edgeType == ET_LINE || edgeType == ET_PLINE ? LORouteExtStraight : LORouteExtNURBS);
gvputs(job, "<ShapeSplittable>1</ShapeSplittable>\n");
gvputs(job, "</Layout>\n");
PrintTexts(job);
/* output Line, Fill, Geom */
- graphic->Print(job, first, last);
+ graphic->Print(job, first, last, edgeType != ET_LINE && edgeType != ET_PLINE);
gvputs(job, "</Shape>\n");
}