# HG changeset patch # User alpar # Date 1105914891 0 # Node ID 5b7ca75297b52f204643352813d33a7f3594a945 # Parent 320a0f083ca13166bfa7f70240ebf7adee8dce37 - Parallel edges look a bit better - Possibility to insert verbatim PS blocks for each node diff -r 320a0f083ca1 -r 5b7ca75297b5 src/lemon/graph_to_eps.h --- a/src/lemon/graph_to_eps.h Sun Jan 16 22:31:26 2005 +0000 +++ b/src/lemon/graph_to_eps.h Sun Jan 16 22:34:51 2005 +0000 @@ -105,6 +105,10 @@ ConstMap _nodeTexts; double _nodeTextSize; + bool _showNodePsText; + ConstMap _nodePsTexts; + char *_nodePsTextsPreamble; + bool _undir; bool _pleaseRemoveOsStream; ///Constructor @@ -128,6 +132,7 @@ _showNodes(true), _showEdges(true), _enableParallel(false), _parEdgeDist(1), _showNodeText(false), _nodeTexts(false), _nodeTextSize(1), + _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0), _undir(false), _pleaseRemoveOsStream(_pros) {} }; @@ -224,7 +229,33 @@ _showNodeText=true; return GraphToEps >(NodeTextsTraits(*this,x)); } - template struct EdgeWidthsTraits : public T { + template struct NodePsTextsTraits : public T { + const X &_nodePsTexts; + NodePsTextsTraits(const T &t,const X &x) : T(t), _nodePsTexts(x) {} + }; + ///Inserts a PostScript block to the nodes + + ///With this command it is possible to insert a verbatim PostScript + ///block to the nodes. + ///The PS current point will be moved to the centre of the node before + ///the PostScript block inserted. + /// + ///Before and after the block a newline character is inserted to you + ///don't have to bother with the separators. + /// + ///\param x must be a node map with type that can be pushed to a standard + ///ostream. + /// + ///\sa nodePsTextsPreamble() + ///\todo Offer the choise not to move to the centre but pass the coordinates + ///to the Postscript block inserted. + template GraphToEps > nodePsTexts(const X &x) + { + dontPrint=true; + _showNodePsText=true; + return GraphToEps >(NodePsTextsTraits(*this,x)); + } + template struct EdgeWidthsTraits : public T { const X &_edgeWidths; EdgeWidthsTraits(const T &t,const X &x) : T(t), _edgeWidths(x) {} }; @@ -337,6 +368,14 @@ ///Sets the size of the node texts /// GraphToEps &nodeTextSize(double d) {_nodeTextSize=d;return *this;} + ///Gives a preamble block for node Postscript block. + + ///Gives a preamble block for node Postscript block. + /// + ///\sa nodePsTexts() + GraphToEps & nodePsTextsPreamble(const char *str) { + _nodePsTextsPreamble=s ;return *this; + } ///Sets whether the the graph is undirected ///Sets whether the the graph is undirected @@ -401,9 +440,8 @@ os << "\ngsave\n"; if(_scale!=1.0) os << _scale << " dup scale\n"; - os << "%Edges:\ngsave\n"; - - if(_showEdges) + if(_showEdges) { + os << "%Edges:\ngsave\n"; if(_enableParallel) { std::vector el; for(EdgeIt e(g);e!=INVALID;++e) @@ -419,21 +457,29 @@ sw+=_edgeWidths[*e]*_edgeWidthScale+_parEdgeDist; sw-=_parEdgeDist; sw/=-2.0; - xy d(_coords[g.target(*i)]-_coords[g.source(*i)]); - double l=sqrt(d.normSquare()); - d/=l; - + xy dvec(_coords[g.target(*i)]-_coords[g.source(*i)]); + double l=sqrt(dvec.normSquare()); + xy d(dvec/l); + xy m; +// m=xy(_coords[g.target(*i)]+_coords[g.source(*i)])/2.0; + +// m=xy(_coords[g.source(*i)])+ +// dvec*(double(_nodeSizes[g.source(*i)])/ +// (_nodeSizes[g.source(*i)]+_nodeSizes[g.target(*i)])); + + m=xy(_coords[g.source(*i)])+ + d*(l+_nodeSizes[g.source(*i)]-_nodeSizes[g.target(*i)])/2.0; + for(typename std::vector::iterator e=i;e!=j;++e) { sw+=_edgeWidths[*e]*_edgeWidthScale/2.0; - xy m(_coords[g.target(*e)]+_coords[g.source(*e)]); - m=m/2.0+rot(d)*sw/.75; + xy mm=m+rot(d)*sw/.75; if(_drawArrows) { const int INERPOL_PREC=20; xy s=_coords[g.source(*e)]; xy t=_coords[g.target(*e)]; double rn=_nodeSizes[g.target(*e)]*_nodeScale; rn*=rn; - Bezier3 bez(s,m,m,t); + Bezier3 bez(s,mm,mm,t); double t1=0,t2=1; for(int i=0;irn) t1=(t1+t2)/2; @@ -472,7 +518,7 @@ else { os << _coords[g.source(*e)].x << ' ' << _coords[g.source(*e)].y << ' ' - << m.x << ' ' << m.y << ' ' + << mm.x << ' ' << mm.y << ' ' << _coords[g.target(*e)].x << ' ' << _coords[g.target(*e)].y << ' ' << _edgeColors[*e].getR() << ' ' @@ -509,24 +555,37 @@ << _edgeColors[e].getG() << ' ' << _edgeColors[e].getB() << ' ' << _edgeWidths[e]*_edgeWidthScale << " l\n"; - os << "grestore\n%Nodes:\ngsave\n"; - if(_showNodes) + os << "grestore\n"; + } + if(_showNodes) { + os << "%Nodes:\ngsave\n"; for(NodeIt n(g);n!=INVALID;++n) os << _coords[n].x << ' ' << _coords[n].y << ' ' << _nodeSizes[n]*_nodeScale << ' ' << _nodeColors[n].getR() << ' ' << _nodeColors[n].getG() << ' ' - << _nodeColors[n].getB() << " n\n"; + << _nodeColors[n].getB() << " n\n"; + os << "grestore\n"; + } if(_showNodeText) { - os << "grestore\n%Node texts:\ngsave\n"; + os << "%Node texts:\ngsave\n"; os << "/fosi " << _nodeTextSize << " def\n"; os << "(Helvetica) findfont fosi scalefont setfont\n"; os << "0 0 0 setrgbcolor\n"; for(NodeIt n(g);n!=INVALID;++n) os << _coords[n].x << ' ' << _coords[n].y << " (" << _nodeTexts[n] << ") cshow\n"; + os << "grestore\n"; } - os << "grestore\ngrestore\n"; + if(_showNodePsText) { + os << "%Node PS blocks:\ngsave\n"; + for(NodeIt n(g);n!=INVALID;++n) + os << _coords[n].x << ' ' << _coords[n].y + << " moveto\n" << _nodePsTexts[n] << "\n"; + os << "grestore\n"; + } + + os << "grestore\n"; //CleanUp: if(_pleaseRemoveOsStream) {delete &os;} @@ -576,22 +635,6 @@ (DefaultGraphToEpsTraits(g,*new std::ofstream(file_name),true)); } -//Generates an EPS file from a graph. -//\param g is a reference to the graph to be printed -//\param file_name is the output file_name. -// -//This function also has a lot of \ref named-templ-param "named parameters", -//they are declared as the members of class \ref GraphToEps. The following -//example shows how to use these parameters. -//\code -// graphToEps(g).scale(10).coords(coords) -// .nodeScale(2).nodeSizes(sizes) -// .edgeWidthScale(.4); -//\endcode -//\sa GraphToEps -//\todo Avoid duplicated documentation -//\bug Exception handling is missing? (Or we can just ignore it?) - } //END OF NAMESPACE LEMON #endif // LEMON_GRAPH_TO_EPS_H