]> granicus.if.org Git - graphviz/commitdiff
when edge type is line or polyline, force Visio connectors to be straight
authorglenlow <devnull@localhost>
Tue, 7 Apr 2009 04:12:49 +0000 (04:12 +0000)
committerglenlow <devnull@localhost>
Tue, 7 Apr 2009 04:12:49 +0000 (04:12 +0000)
plugin/visio/VisioGraphic.cpp
plugin/visio/VisioGraphic.h
plugin/visio/VisioRender.cpp
plugin/visio/VisioRender.h

index d55c4a88611ef5f35cd9495d96fe9da153841fe9..9a495ac3fb1b782ec95667b8b433f3d283d5a214 100644 (file)
@@ -73,7 +73,7 @@ namespace Visio
                _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)
@@ -204,7 +204,7 @@ namespace Visio
                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)
@@ -223,42 +223,70 @@ namespace Visio
                        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");
        }
@@ -282,7 +310,7 @@ namespace Visio
                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)
@@ -356,7 +384,7 @@ namespace Visio
                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)
@@ -565,14 +593,14 @@ namespace Visio
                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);
                
        }
        
index 167e5a14f57acaa2a6925ab1b744c69d37ddd332..3fe374894bd49c5dfdaacf08de5632f1c196e3bb 100644 (file)
@@ -70,7 +70,7 @@ namespace Visio
                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
@@ -84,7 +84,7 @@ namespace Visio
                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;
@@ -114,7 +114,7 @@ namespace Visio
                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:
@@ -129,7 +129,7 @@ namespace Visio
                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;
@@ -143,7 +143,7 @@ namespace Visio
                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;
 
        };
        
@@ -165,7 +165,7 @@ namespace Visio
                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);
index 7e490147f7d0d3dc516ff2b9eb11b94a0283aaf6..80b5fea9939528e8762d0a828d7f487e930a7e4f 100644 (file)
@@ -16,6 +16,8 @@
 
 #include "VisioRender.h"
 
+#include "const.h"
+#include "macros.h"
 #include "gvcjob.h"
 #include "gvio.h"
 
@@ -24,6 +26,21 @@ namespace Visio
        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),
@@ -157,16 +174,22 @@ namespace Visio
                
                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
@@ -272,7 +295,7 @@ namespace Visio
                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");
        }
@@ -304,12 +327,12 @@ namespace Visio
                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();
@@ -360,9 +383,9 @@ namespace Visio
                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");
                
@@ -428,7 +451,7 @@ namespace Visio
                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");
        }
index f3f01aa263ddab145a1f5eaf5fe501181be121db..bc699fc56fc167ef7600f5a90ee41b88fc43dd1d 100644 (file)
@@ -70,8 +70,8 @@ namespace Visio
                /* output the graphic as a subshape of a top level shape, given its id and bounds */
                void PrintInnerShape(GVJ_t* job, Graphic* graphic, unsigned int outerId, boxf outerBounds);
                
-               /* output the graphic as an edge shape, given the start and end node ids */
-               void PrintEdgeShape(GVJ_t* job, Graphic* graphic, unsigned int beginId, unsigned int endId);
+               /* 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);
                
                /* output all the collected texts */
                void PrintTexts(GVJ_t* job);