From: glenlow Date: Fri, 10 Apr 2009 00:25:08 +0000 (+0000) Subject: cleaned up connectable object model X-Git-Tag: LAST_LIBGRAPH~32^2~2177 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7db66d2ff8d25c7983e68a06ae3e8fdf401ab49f;p=graphviz cleaned up connectable object model --- diff --git a/plugin/visio/VisioGraphic.cpp b/plugin/visio/VisioGraphic.cpp index 9a495ac3f..d7252a5d8 100644 --- a/plugin/visio/VisioGraphic.cpp +++ b/plugin/visio/VisioGraphic.cpp @@ -94,28 +94,12 @@ namespace Visio bounds.UR.y = _points[1].y; return bounds; } - - pointf Ellipse::GetFirst() const - { - return _points[0]; - } - - pointf Ellipse::GetLast() const - { - return _points[1]; - } - - pointf Ellipse::GetCenter() const - { - /* only called for edges, so return a null point */ - pointf center = {0, 0}; - return center; - } - - bool Ellipse::IsConnectable() const + + Connection Ellipse::GetConnection() const { - /* cannot be a connector */ - return false; + Connection connection; + connection.connectable = false; + return connection; } Path::Path(pointf* points, int pointCount) @@ -161,24 +145,18 @@ namespace Visio return bounds; } - pointf Path::GetFirst() const - { - return _points[0]; - } - - pointf Path::GetLast() const - { - return _points[_pointCount - 1]; - } - Bezier::Bezier(pointf* points, int pointCount, bool filled): Path(points, pointCount), _filled(filled) { } - pointf Bezier::GetCenter() const + Connection Bezier::GetConnection() const { + Connection connection; + connection.connectable = true; + connection.first = _points[0]; + connection.last = _points[1]; if (_pointCount >= 4 && _pointCount % 2 == 0) { /* the central control polygon for the bezier curve */ @@ -188,20 +166,14 @@ namespace Visio pointf p3 = _points[_pointCount / 2 + 1]; /* use de Casteljou's algorithm to get a midpoint */ - pointf center; - center.x = 0.125 * p0.x + 0.375 * p1.x + 0.375 * p2.x + 0.125 * p3.x; - center.y = 0.125 * p0.y + 0.375 * p1.y + 0.375 * p2.y + 0.125 * p3.y; - return center; + connection.center.x = 0.125 * p0.x + 0.375 * p1.x + 0.375 * p2.x + 0.125 * p3.x; + connection.center.y = 0.125 * p0.y + 0.375 * p1.y + 0.375 * p2.y + 0.125 * p3.y; } else - /* just return the middle point */ - return _points[_pointCount / 2]; - } - - bool Bezier::IsConnectable() const - { - /* can be a connector */ - return true; + /* just return the middle point */ + connection.center = _points[_pointCount / 2]; + + return connection; } void Bezier::Print(GVJ_t* job, pointf first, pointf last, bool allowCurves) const @@ -297,19 +269,13 @@ namespace Visio { } - pointf Polygon::GetCenter() const + Connection Polygon::GetConnection() const { - /* should not get called, return a null point */ - pointf center = {0, 0}; - return center; + Connection connection; + connection.connectable = false; + return connection; } - bool Polygon::IsConnectable() const - { - /* cannot be a connector */ - return false; - } - void Polygon::Print(GVJ_t* job, pointf first, pointf last, bool allowCurves) const { gvputs(job, "\n"); @@ -359,29 +325,11 @@ namespace Visio { } - pointf Polyline::GetCenter() const + Connection Polyline::GetConnection() const { - if (_pointCount >= 2 && _pointCount % 2 == 0) - { - /* the center two points */ - pointf p0 = _points[_pointCount / 2 - 1]; - pointf p1 = _points[_pointCount / 2]; - - /* take the midpoint */ - pointf center; - center.x = (p0.x + p1.x) * 0.5; - center.y = (p0.y + p1.y) * 0.5; - return center; - } - else - /* just return the middle point */ - return _points[_pointCount / 2]; - } - - bool Polyline::IsConnectable() const - { - /* cannot be a connector */ - return false; + Connection connection; + connection.connectable = false; + return connection; } void Polyline::Print(GVJ_t* job, pointf first, pointf last, bool allowCurves) const @@ -573,26 +521,11 @@ namespace Visio return _geom->GetBounds(); } - pointf Graphic::GetFirst() const + Connection Graphic::GetConnection() const { - return _geom->GetFirst(); + return _geom->GetConnection(); } - - pointf Graphic::GetLast() const - { - return _geom->GetLast(); - } - - pointf Graphic::GetCenter() const - { - return _geom->GetCenter(); - } - - bool Graphic::IsConnectable() const - { - return _geom->IsConnectable(); - } - + void Graphic::Print(GVJ_t* job, pointf first, pointf last, bool allowCurves) const { if (_line) diff --git a/plugin/visio/VisioGraphic.h b/plugin/visio/VisioGraphic.h index 3fe374894..2a8c092e3 100644 --- a/plugin/visio/VisioGraphic.h +++ b/plugin/visio/VisioGraphic.h @@ -60,14 +60,19 @@ namespace Visio /* Geom VDX element */ + struct Connection + { + bool connectable; + pointf first; + pointf last; + pointf center; + }; + class Geom { public: - virtual boxf GetBounds() const = 0; /* bounding box -- used by node logic */ - virtual pointf GetFirst() const = 0; /* first point -- used by edge logic */ - virtual pointf GetLast() const = 0; /* last point -- used by edge logic */ - virtual pointf GetCenter() const = 0; /* midpoint of the path -- used by text logic */ - virtual bool IsConnectable() const = 0; /* whether this geom can be turned into a connector -- used by edge logic */ + virtual boxf GetBounds() const = 0; /* bounding box -- used by node logic */ + virtual Connection GetConnection() const = 0; /* first, last and center points -- 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, bool allowCurves) const = 0; @@ -79,10 +84,7 @@ namespace Visio Ellipse(pointf* points, bool filled); virtual boxf GetBounds() const; - virtual pointf GetFirst() const; - virtual pointf GetLast() const; - virtual pointf GetCenter() const; - virtual bool IsConnectable() const; + virtual Connection GetConnection() const; void Print(GVJ_t* job, pointf first, pointf last, bool allowCurves) const; @@ -98,8 +100,6 @@ namespace Visio ~Path(); virtual boxf GetBounds() const; - virtual pointf GetFirst() const; - virtual pointf GetLast() const; protected: pointf* _points; @@ -111,8 +111,7 @@ namespace Visio public: Bezier(pointf* points, int pointCount, bool filled); - virtual pointf GetCenter() const; - virtual bool IsConnectable() const; + virtual Connection GetConnection() const; virtual void Print(GVJ_t* job, pointf first, pointf last, bool allowCurves) const; @@ -126,8 +125,7 @@ namespace Visio public: Polygon(pointf* points, int pointCount, bool filled); - virtual pointf GetCenter() const; - virtual bool IsConnectable() const; + virtual Connection GetConnection() const; virtual void Print(GVJ_t* job, pointf first, pointf last, bool allowCurves) const; @@ -140,8 +138,7 @@ namespace Visio public: Polyline(pointf* points, int pointCount); - virtual pointf GetCenter() const; - virtual bool IsConnectable() const; + virtual Connection GetConnection() const; void Print(GVJ_t* job, pointf first, pointf last, bool allowCurves) const; @@ -160,10 +157,7 @@ namespace Visio ~Graphic(); boxf GetBounds() const; - pointf GetFirst() const; - pointf GetLast() const; - pointf GetCenter() const; - bool IsConnectable() const; + Connection GetConnection() const; void Print(GVJ_t* job, pointf first, pointf last, bool allowCurves) const; diff --git a/plugin/visio/VisioRender.cpp b/plugin/visio/VisioRender.cpp index 80b5fea99..ddf693188 100644 --- a/plugin/visio/VisioRender.cpp +++ b/plugin/visio/VisioRender.cpp @@ -183,15 +183,12 @@ namespace Visio /* 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, - EDGE_TYPE(edge->head->graph->root)); + if (firstConnector && 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 PrintOuterShape(job, *nextGraphic); @@ -332,128 +329,130 @@ namespace Visio gvputs(job, "\n"); } - void Render::PrintEdgeShape(GVJ_t* job, Graphic* graphic, unsigned int beginId, unsigned int endId, int edgeType) + bool Render::PrintEdgeShape(GVJ_t* job, Graphic* graphic, unsigned int beginId, unsigned int endId, int edgeType) { - pointf first = graphic->GetFirst(); - pointf last = graphic->GetLast(); - - bool zeroWidth = first.x == last.x; - bool zeroHeight = first.y == last.y; + Connection connection = graphic->GetConnection(); + if (connection.connectable) + { + bool zeroWidth = connection.first.x == connection.last.x; + bool zeroHeight = connection.first.y == connection.last.y; - gvprintf(job, "\n", ++_shapeId); - - /* XForm depends on XForm1D */ - gvputs(job, "\n"); - gvputs(job, "\n"); - gvputs(job, "\n"); - if (zeroWidth) - gvprintf(job, "\n", 2 * ZERO_ADJUST); /* if vertical line, expand width to 0.25 inches */ - else - gvputs(job, "\n"); - if (zeroHeight) - gvprintf(job, "\n", 2 * ZERO_ADJUST); /* if horizontal line, expand height to 0.25 inches */ - else - gvputs(job, "\n"); - gvputs(job, "\n"); - gvputs(job, "\n"); + gvprintf(job, "\n", ++_shapeId); - /* XForm1D walking glue makes connector attach to its nodes */ - gvputs(job, "\n"); - gvprintf(job, "%f\n", first.x * INCHES_PER_POINT); - gvprintf(job, "%f\n", first.y * INCHES_PER_POINT); - gvprintf(job, "%f\n", last.x * INCHES_PER_POINT); - gvprintf(job, "%f\n", last.y * INCHES_PER_POINT); - gvputs(job, "\n"); - - gvputs(job, "\n"); - gvputs(job, "1\n"); - gvputs(job, "1\n"); - gvputs(job, "\n"); - - gvputs(job, "\n"); - gvputs(job, "1\n"); - gvputs(job, "2\n"); - gvputs(job, "2\n"); - if (beginId && endId) - { - gvprintf(job, "\n", beginId); - gvprintf(job, "\n", endId); - } - gvputs(job, "2\n"); - gvputs(job, "\n"); - - gvputs(job, "\n"); - gvprintf(job, "%d\n", edgeType == ET_LINE ? LORouteCenterToCenter : LORouteRightAngle); - gvputs(job, "6\n"); - gvprintf(job, "%d\n", edgeType == ET_LINE || edgeType == ET_PLINE ? LORouteExtStraight : LORouteExtNURBS); - gvputs(job, "1\n"); - gvputs(job, "\n"); - - /* output Hyperlink */ - PrintHyperlinks(job); + /* XForm depends on XForm1D */ + gvputs(job, "\n"); + gvputs(job, "\n"); + gvputs(job, "\n"); + if (zeroWidth) + gvprintf(job, "\n", 2 * ZERO_ADJUST); /* if vertical line, expand width to 0.25 inches */ + else + gvputs(job, "\n"); + if (zeroHeight) + gvprintf(job, "\n", 2 * ZERO_ADJUST); /* if horizontal line, expand height to 0.25 inches */ + else + gvputs(job, "\n"); + gvputs(job, "\n"); + gvputs(job, "\n"); + + /* XForm1D walking glue makes connector attach to its nodes */ + gvputs(job, "\n"); + gvprintf(job, "%f\n", connection.first.x * INCHES_PER_POINT); + gvprintf(job, "%f\n", connection.first.y * INCHES_PER_POINT); + gvprintf(job, "%f\n", connection.last.x * INCHES_PER_POINT); + gvprintf(job, "%f\n", connection.last.y * INCHES_PER_POINT); + gvputs(job, "\n"); + + gvputs(job, "\n"); + gvputs(job, "1\n"); + gvputs(job, "1\n"); + gvputs(job, "\n"); + + gvputs(job, "\n"); + gvputs(job, "1\n"); + gvputs(job, "2\n"); + gvputs(job, "2\n"); + if (beginId && endId) + { + gvprintf(job, "\n", beginId); + gvprintf(job, "\n", endId); + } + gvputs(job, "2\n"); + gvputs(job, "\n"); + + gvputs(job, "\n"); + gvprintf(job, "%d\n", edgeType == ET_LINE ? LORouteCenterToCenter : LORouteRightAngle); + gvputs(job, "6\n"); + gvprintf(job, "%d\n", edgeType == ET_LINE || edgeType == ET_PLINE ? LORouteExtStraight : LORouteExtNURBS); + gvputs(job, "1\n"); + gvputs(job, "\n"); + + /* output Hyperlink */ + PrintHyperlinks(job); - /* TextXForm depends on custom control */ - gvputs(job, "\n"); - gvputs(job, "\n"); - gvputs(job, "\n"); - gvputs(job, "\n"); - gvputs(job, "\n"); - gvputs(job, "\n"); + /* TextXForm depends on custom control */ + gvputs(job, "\n"); + gvputs(job, "\n"); + gvputs(job, "\n"); + gvputs(job, "\n"); + gvputs(job, "\n"); + gvputs(job, "\n"); - if (zeroWidth) - { - first.x -= ZERO_ADJUST; - last.x += ZERO_ADJUST; - } - if (zeroHeight) - { - first.y -= ZERO_ADJUST; - last.y += ZERO_ADJUST; - } - - /* compute center to attach text to. if text has been rendered, use overall bounding box center; if not, use the path center */ - pointf textCenter; - if (_texts.size() > 0) - { - boxf outerTextBounds = _texts[0]->GetBounds(); + if (zeroWidth) + { + connection.first.x -= ZERO_ADJUST; + connection.last.x += ZERO_ADJUST; + } + if (zeroHeight) + { + connection.first.y -= ZERO_ADJUST; + connection.last.y += ZERO_ADJUST; + } - for (Texts::const_iterator nextText = _texts.begin() + 1, lastText = _texts.end(); - nextText != lastText; - ++nextText) + /* compute center to attach text to. if text has been rendered, use overall bounding box center; if not, use the path center */ + pointf textCenter; + if (_texts.size() > 0) { - boxf innerTextBounds = (*nextText)->GetBounds(); - if (outerTextBounds.LL.x > innerTextBounds.LL.x) - outerTextBounds.LL.x = innerTextBounds.LL.x; - if (outerTextBounds.LL.y > innerTextBounds.LL.y) - outerTextBounds.LL.y = innerTextBounds.LL.y; - if (outerTextBounds.UR.x < innerTextBounds.UR.x) - outerTextBounds.UR.x = innerTextBounds.UR.x; - if (outerTextBounds.UR.y < innerTextBounds.UR.y) - outerTextBounds.UR.y = innerTextBounds.UR.y; + boxf outerTextBounds = _texts[0]->GetBounds(); + + for (Texts::const_iterator nextText = _texts.begin() + 1, lastText = _texts.end(); + nextText != lastText; + ++nextText) + { + boxf innerTextBounds = (*nextText)->GetBounds(); + if (outerTextBounds.LL.x > innerTextBounds.LL.x) + outerTextBounds.LL.x = innerTextBounds.LL.x; + if (outerTextBounds.LL.y > innerTextBounds.LL.y) + outerTextBounds.LL.y = innerTextBounds.LL.y; + if (outerTextBounds.UR.x < innerTextBounds.UR.x) + outerTextBounds.UR.x = innerTextBounds.UR.x; + if (outerTextBounds.UR.y < innerTextBounds.UR.y) + outerTextBounds.UR.y = innerTextBounds.UR.y; + } + textCenter.x = (outerTextBounds.LL.x + outerTextBounds.UR.x) / 2.0; + textCenter.y = (outerTextBounds.LL.y + outerTextBounds.UR.y) / 2.0; } - textCenter.x = (outerTextBounds.LL.x + outerTextBounds.UR.x) / 2.0; - textCenter.y = (outerTextBounds.LL.y + outerTextBounds.UR.y) / 2.0; - } - else - textCenter = graphic->GetCenter(); - - /* Control for positioning text */ - gvputs(job, "\n"); - gvprintf(job, "%f\n", (textCenter.x - first.x) * INCHES_PER_POINT); - gvprintf(job, "%f\n", (textCenter.y - first.y) * INCHES_PER_POINT); - gvputs(job, "\n"); - gvputs(job, "\n"); - gvputs(job, "5\n"); - gvputs(job, "0\n"); - gvputs(job, "\n"); + else + textCenter = connection.center; - /* output Para, Char, Text */ - PrintTexts(job); - - /* output Line, Fill, Geom */ - graphic->Print(job, first, last, edgeType != ET_LINE && edgeType != ET_PLINE); - - gvputs(job, "\n"); + /* Control for positioning text */ + gvputs(job, "\n"); + gvprintf(job, "%f\n", (textCenter.x - connection.first.x) * INCHES_PER_POINT); + gvprintf(job, "%f\n", (textCenter.y - connection.first.y) * INCHES_PER_POINT); + gvputs(job, "\n"); + gvputs(job, "\n"); + gvputs(job, "5\n"); + gvputs(job, "0\n"); + gvputs(job, "\n"); + + /* output Para, Char, Text */ + PrintTexts(job); + + /* output Line, Fill, Geom */ + graphic->Print(job, connection.first, connection.last, edgeType != ET_LINE && edgeType != ET_PLINE); + + gvputs(job, "\n"); + } + return connection.connectable; } void Render::PrintTexts(GVJ_t* job) diff --git a/plugin/visio/VisioRender.h b/plugin/visio/VisioRender.h index bc699fc56..66cc72c99 100644 --- a/plugin/visio/VisioRender.h +++ b/plugin/visio/VisioRender.h @@ -71,7 +71,7 @@ namespace Visio void PrintInnerShape(GVJ_t* job, Graphic* graphic, unsigned int outerId, boxf outerBounds); /* output the graphic as an edge connector, given the start and end node ids */ - void PrintEdgeShape(GVJ_t* job, Graphic* graphic, unsigned int beginId, unsigned int endId, int edgeType); + bool PrintEdgeShape(GVJ_t* job, Graphic* graphic, unsigned int beginId, unsigned int endId, int edgeType); /* output all the collected texts */ void PrintTexts(GVJ_t* job);