1.1 --- a/src/lemon/graph_to_eps.h Sun Jan 16 22:31:26 2005 +0000
1.2 +++ b/src/lemon/graph_to_eps.h Sun Jan 16 22:34:51 2005 +0000
1.3 @@ -105,6 +105,10 @@
1.4 ConstMap<typename Graph::Node,bool > _nodeTexts;
1.5 double _nodeTextSize;
1.6
1.7 + bool _showNodePsText;
1.8 + ConstMap<typename Graph::Node,bool > _nodePsTexts;
1.9 + char *_nodePsTextsPreamble;
1.10 +
1.11 bool _undir;
1.12 bool _pleaseRemoveOsStream;
1.13 ///Constructor
1.14 @@ -128,6 +132,7 @@
1.15 _showNodes(true), _showEdges(true),
1.16 _enableParallel(false), _parEdgeDist(1),
1.17 _showNodeText(false), _nodeTexts(false), _nodeTextSize(1),
1.18 + _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0),
1.19 _undir(false),
1.20 _pleaseRemoveOsStream(_pros) {}
1.21 };
1.22 @@ -224,7 +229,33 @@
1.23 _showNodeText=true;
1.24 return GraphToEps<NodeTextsTraits<X> >(NodeTextsTraits<X>(*this,x));
1.25 }
1.26 - template<class X> struct EdgeWidthsTraits : public T {
1.27 + template<class X> struct NodePsTextsTraits : public T {
1.28 + const X &_nodePsTexts;
1.29 + NodePsTextsTraits(const T &t,const X &x) : T(t), _nodePsTexts(x) {}
1.30 + };
1.31 + ///Inserts a PostScript block to the nodes
1.32 +
1.33 + ///With this command it is possible to insert a verbatim PostScript
1.34 + ///block to the nodes.
1.35 + ///The PS current point will be moved to the centre of the node before
1.36 + ///the PostScript block inserted.
1.37 + ///
1.38 + ///Before and after the block a newline character is inserted to you
1.39 + ///don't have to bother with the separators.
1.40 + ///
1.41 + ///\param x must be a node map with type that can be pushed to a standard
1.42 + ///ostream.
1.43 + ///
1.44 + ///\sa nodePsTextsPreamble()
1.45 + ///\todo Offer the choise not to move to the centre but pass the coordinates
1.46 + ///to the Postscript block inserted.
1.47 + template<class X> GraphToEps<NodePsTextsTraits<X> > nodePsTexts(const X &x)
1.48 + {
1.49 + dontPrint=true;
1.50 + _showNodePsText=true;
1.51 + return GraphToEps<NodePsTextsTraits<X> >(NodePsTextsTraits<X>(*this,x));
1.52 + }
1.53 + template<class X> struct EdgeWidthsTraits : public T {
1.54 const X &_edgeWidths;
1.55 EdgeWidthsTraits(const T &t,const X &x) : T(t), _edgeWidths(x) {}
1.56 };
1.57 @@ -337,6 +368,14 @@
1.58 ///Sets the size of the node texts
1.59 ///
1.60 GraphToEps<T> &nodeTextSize(double d) {_nodeTextSize=d;return *this;}
1.61 + ///Gives a preamble block for node Postscript block.
1.62 +
1.63 + ///Gives a preamble block for node Postscript block.
1.64 + ///
1.65 + ///\sa nodePsTexts()
1.66 + GraphToEps<T> & nodePsTextsPreamble(const char *str) {
1.67 + _nodePsTextsPreamble=s ;return *this;
1.68 + }
1.69 ///Sets whether the the graph is undirected
1.70
1.71 ///Sets whether the the graph is undirected
1.72 @@ -401,9 +440,8 @@
1.73 os << "\ngsave\n";
1.74 if(_scale!=1.0) os << _scale << " dup scale\n";
1.75
1.76 - os << "%Edges:\ngsave\n";
1.77 -
1.78 - if(_showEdges)
1.79 + if(_showEdges) {
1.80 + os << "%Edges:\ngsave\n";
1.81 if(_enableParallel) {
1.82 std::vector<Edge> el;
1.83 for(EdgeIt e(g);e!=INVALID;++e)
1.84 @@ -419,21 +457,29 @@
1.85 sw+=_edgeWidths[*e]*_edgeWidthScale+_parEdgeDist;
1.86 sw-=_parEdgeDist;
1.87 sw/=-2.0;
1.88 - xy<double> d(_coords[g.target(*i)]-_coords[g.source(*i)]);
1.89 - double l=sqrt(d.normSquare());
1.90 - d/=l;
1.91 -
1.92 + xy<double> dvec(_coords[g.target(*i)]-_coords[g.source(*i)]);
1.93 + double l=sqrt(dvec.normSquare());
1.94 + xy<double> d(dvec/l);
1.95 + xy<double> m;
1.96 +// m=xy<double>(_coords[g.target(*i)]+_coords[g.source(*i)])/2.0;
1.97 +
1.98 +// m=xy<double>(_coords[g.source(*i)])+
1.99 +// dvec*(double(_nodeSizes[g.source(*i)])/
1.100 +// (_nodeSizes[g.source(*i)]+_nodeSizes[g.target(*i)]));
1.101 +
1.102 + m=xy<double>(_coords[g.source(*i)])+
1.103 + d*(l+_nodeSizes[g.source(*i)]-_nodeSizes[g.target(*i)])/2.0;
1.104 +
1.105 for(typename std::vector<Edge>::iterator e=i;e!=j;++e) {
1.106 sw+=_edgeWidths[*e]*_edgeWidthScale/2.0;
1.107 - xy<double> m(_coords[g.target(*e)]+_coords[g.source(*e)]);
1.108 - m=m/2.0+rot(d)*sw/.75;
1.109 + xy<double> mm=m+rot(d)*sw/.75;
1.110 if(_drawArrows) {
1.111 const int INERPOL_PREC=20;
1.112 xy<double> s=_coords[g.source(*e)];
1.113 xy<double> t=_coords[g.target(*e)];
1.114 double rn=_nodeSizes[g.target(*e)]*_nodeScale;
1.115 rn*=rn;
1.116 - Bezier3 bez(s,m,m,t);
1.117 + Bezier3 bez(s,mm,mm,t);
1.118 double t1=0,t2=1;
1.119 for(int i=0;i<INERPOL_PREC;++i)
1.120 if((bez((t1+t2)/2)-t).normSquare()>rn) t1=(t1+t2)/2;
1.121 @@ -472,7 +518,7 @@
1.122 else {
1.123 os << _coords[g.source(*e)].x << ' '
1.124 << _coords[g.source(*e)].y << ' '
1.125 - << m.x << ' ' << m.y << ' '
1.126 + << mm.x << ' ' << mm.y << ' '
1.127 << _coords[g.target(*e)].x << ' '
1.128 << _coords[g.target(*e)].y << ' '
1.129 << _edgeColors[*e].getR() << ' '
1.130 @@ -509,24 +555,37 @@
1.131 << _edgeColors[e].getG() << ' '
1.132 << _edgeColors[e].getB() << ' '
1.133 << _edgeWidths[e]*_edgeWidthScale << " l\n";
1.134 - os << "grestore\n%Nodes:\ngsave\n";
1.135 - if(_showNodes)
1.136 + os << "grestore\n";
1.137 + }
1.138 + if(_showNodes) {
1.139 + os << "%Nodes:\ngsave\n";
1.140 for(NodeIt n(g);n!=INVALID;++n)
1.141 os << _coords[n].x << ' ' << _coords[n].y << ' '
1.142 << _nodeSizes[n]*_nodeScale << ' '
1.143 << _nodeColors[n].getR() << ' '
1.144 << _nodeColors[n].getG() << ' '
1.145 - << _nodeColors[n].getB() << " n\n";
1.146 + << _nodeColors[n].getB() << " n\n";
1.147 + os << "grestore\n";
1.148 + }
1.149 if(_showNodeText) {
1.150 - os << "grestore\n%Node texts:\ngsave\n";
1.151 + os << "%Node texts:\ngsave\n";
1.152 os << "/fosi " << _nodeTextSize << " def\n";
1.153 os << "(Helvetica) findfont fosi scalefont setfont\n";
1.154 os << "0 0 0 setrgbcolor\n";
1.155 for(NodeIt n(g);n!=INVALID;++n)
1.156 os << _coords[n].x << ' ' << _coords[n].y
1.157 << " (" << _nodeTexts[n] << ") cshow\n";
1.158 + os << "grestore\n";
1.159 }
1.160 - os << "grestore\ngrestore\n";
1.161 + if(_showNodePsText) {
1.162 + os << "%Node PS blocks:\ngsave\n";
1.163 + for(NodeIt n(g);n!=INVALID;++n)
1.164 + os << _coords[n].x << ' ' << _coords[n].y
1.165 + << " moveto\n" << _nodePsTexts[n] << "\n";
1.166 + os << "grestore\n";
1.167 + }
1.168 +
1.169 + os << "grestore\n";
1.170
1.171 //CleanUp:
1.172 if(_pleaseRemoveOsStream) {delete &os;}
1.173 @@ -576,22 +635,6 @@
1.174 (DefaultGraphToEpsTraits<G>(g,*new std::ofstream(file_name),true));
1.175 }
1.176
1.177 -//Generates an EPS file from a graph.
1.178 -//\param g is a reference to the graph to be printed
1.179 -//\param file_name is the output file_name.
1.180 -//
1.181 -//This function also has a lot of \ref named-templ-param "named parameters",
1.182 -//they are declared as the members of class \ref GraphToEps. The following
1.183 -//example shows how to use these parameters.
1.184 -//\code
1.185 -// graphToEps(g).scale(10).coords(coords)
1.186 -// .nodeScale(2).nodeSizes(sizes)
1.187 -// .edgeWidthScale(.4);
1.188 -//\endcode
1.189 -//\sa GraphToEps
1.190 -//\todo Avoid duplicated documentation
1.191 -//\bug Exception handling is missing? (Or we can just ignore it?)
1.192 -
1.193 } //END OF NAMESPACE LEMON
1.194
1.195 #endif // LEMON_GRAPH_TO_EPS_H