84 |
84 |
85 ConstMap<typename Graph::Node,Color > _nodeColors; |
85 ConstMap<typename Graph::Node,Color > _nodeColors; |
86 ConstMap<typename Graph::Edge,Color > _edgeColors; |
86 ConstMap<typename Graph::Edge,Color > _edgeColors; |
87 |
87 |
88 ConstMap<typename Graph::Edge,double > _edgeWidths; |
88 ConstMap<typename Graph::Edge,double > _edgeWidths; |
|
89 |
|
90 static const double A4HEIGHT = 841.8897637795276; |
|
91 static const double A4WIDTH = 595.275590551181; |
|
92 static const double A4BORDER = 15; |
|
93 |
89 |
94 |
90 double _edgeWidthScale; |
95 double _edgeWidthScale; |
91 |
96 |
92 double _nodeScale; |
97 double _nodeScale; |
93 double _xBorder, _yBorder; |
98 double _xBorder, _yBorder; |
110 ConstMap<typename Graph::Node,bool > _nodePsTexts; |
115 ConstMap<typename Graph::Node,bool > _nodePsTexts; |
111 char *_nodePsTextsPreamble; |
116 char *_nodePsTextsPreamble; |
112 |
117 |
113 bool _undir; |
118 bool _undir; |
114 bool _pleaseRemoveOsStream; |
119 bool _pleaseRemoveOsStream; |
|
120 |
|
121 bool _scaleToA4; |
|
122 |
115 ///Constructor |
123 ///Constructor |
116 |
124 |
117 ///Constructor |
125 ///Constructor |
118 ///\param _g is a reference to the graph to be printed |
126 ///\param _g is a reference to the graph to be printed |
119 ///\param _os is a reference to the output stream. |
127 ///\param _os is a reference to the output stream. |
133 _showNodes(true), _showEdges(true), |
141 _showNodes(true), _showEdges(true), |
134 _enableParallel(false), _parEdgeDist(1), |
142 _enableParallel(false), _parEdgeDist(1), |
135 _showNodeText(false), _nodeTexts(false), _nodeTextSize(1), |
143 _showNodeText(false), _nodeTexts(false), _nodeTextSize(1), |
136 _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0), |
144 _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0), |
137 _undir(false), |
145 _undir(false), |
138 _pleaseRemoveOsStream(_pros) {} |
146 _pleaseRemoveOsStream(_pros), _scaleToA4(false) {} |
139 }; |
147 }; |
140 |
148 |
141 ///Helper class to implement the named parameters of \ref graphToEps() |
149 ///Helper class to implement the named parameters of \ref graphToEps() |
142 |
150 |
143 ///Helper class to implement the named parameters of \ref graphToEps() |
151 ///Helper class to implement the named parameters of \ref graphToEps() |
144 ///\todo Is 'helper class' a good name for this? |
152 ///\todo Is 'helper class' a good name for this? |
145 /// |
153 /// |
|
154 ///\todo Follow PostScript's DSC. |
|
155 ///\todo Use own dictionary. |
146 template<class T> class GraphToEps : public T |
156 template<class T> class GraphToEps : public T |
147 { |
157 { |
148 typedef typename T::Graph Graph; |
158 typedef typename T::Graph Graph; |
149 typedef typename Graph::Node Node; |
159 typedef typename Graph::Node Node; |
150 typedef typename Graph::NodeIt NodeIt; |
160 typedef typename Graph::NodeIt NodeIt; |
199 CoordsTraits(const T &t,const X &x) : T(t), _coords(x) {} |
209 CoordsTraits(const T &t,const X &x) : T(t), _coords(x) {} |
200 }; |
210 }; |
201 ///Sets the map of the node coordinates |
211 ///Sets the map of the node coordinates |
202 |
212 |
203 ///Sets the map of the node coordinates. |
213 ///Sets the map of the node coordinates. |
204 ///\param x must be a node map with xy<double> or xy<int> values. |
214 ///\param x must be a node map with xy<double> or \ref xy "xy<int>" values. |
205 template<class X> GraphToEps<CoordsTraits<X> > coords(const X &x) { |
215 template<class X> GraphToEps<CoordsTraits<X> > coords(const X &x) { |
206 dontPrint=true; |
216 dontPrint=true; |
207 return GraphToEps<CoordsTraits<X> >(CoordsTraits<X>(*this,x)); |
217 return GraphToEps<CoordsTraits<X> >(CoordsTraits<X>(*this,x)); |
208 } |
218 } |
209 template<class X> struct NodeSizesTraits : public T { |
219 template<class X> struct NodeSizesTraits : public T { |
356 ///Sets the width of the arrowheads |
366 ///Sets the width of the arrowheads |
357 |
367 |
358 ///Sets the width of the arrowheads |
368 ///Sets the width of the arrowheads |
359 /// |
369 /// |
360 GraphToEps<T> &arrowWidth(double d) {_arrowWidth*=d;return *this;} |
370 GraphToEps<T> &arrowWidth(double d) {_arrowWidth*=d;return *this;} |
|
371 |
|
372 ///Scales the drawing to fit to A4 page |
|
373 |
|
374 ///Scales the drawing to fit to A4 page |
|
375 /// |
|
376 GraphToEps<T> &scaleToA4() {_scaleToA4=true;return *this;} |
361 |
377 |
362 ///Enables parallel edges |
378 ///Enables parallel edges |
363 |
379 |
364 ///Enables parallel edges |
380 ///Enables parallel edges |
365 ///\todo Partially implemented |
381 ///\todo Partially implemented |
439 double ns=_nodeSizes[n]*_nodeScale; |
455 double ns=_nodeSizes[n]*_nodeScale; |
440 xy<double> p(ns,ns); |
456 xy<double> p(ns,ns); |
441 bb+=p+_coords[n]; |
457 bb+=p+_coords[n]; |
442 bb+=-p+_coords[n]; |
458 bb+=-p+_coords[n]; |
443 } |
459 } |
444 os << "%%BoundingBox: " |
460 if(!_scaleToA4) os << "%%BoundingBox: " |
445 << bb.left()* _scale-_xBorder << ' ' |
461 << bb.left()* _scale-_xBorder << ' ' |
446 << bb.bottom()*_scale-_yBorder << ' ' |
462 << bb.bottom()*_scale-_yBorder << ' ' |
447 << bb.right()* _scale+_xBorder << ' ' |
463 << bb.right()* _scale+_xBorder << ' ' |
448 << bb.top()* _scale+_yBorder << '\n'; |
464 << bb.top()* _scale+_yBorder << '\n'; |
449 //x1 y1 x2 y2 x3 y3 cr cg cb w |
465 //x1 y1 x2 y2 x3 y3 cr cg cb w |
450 os << "/lb { setlinewidth setrgbcolor newpath moveto\n" |
466 os << "/lb { setlinewidth setrgbcolor newpath moveto\n" |
451 << " 4 2 roll 1 index 1 index curveto stroke } bind def\n"; |
467 << " 4 2 roll 1 index 1 index curveto stroke } bind def\n"; |
452 os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def\n"; |
468 os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def\n"; |
453 //x y r |
469 //x y r |
494 << " closepath fill } bind def\n"; |
510 << " closepath fill } bind def\n"; |
495 os << "/cshow { 2 index 2 index moveto dup stringwidth pop\n" |
511 os << "/cshow { 2 index 2 index moveto dup stringwidth pop\n" |
496 << " neg 2 div fosi .35 mul neg rmoveto show pop pop} def\n"; |
512 << " neg 2 div fosi .35 mul neg rmoveto show pop pop} def\n"; |
497 |
513 |
498 os << "\ngsave\n"; |
514 os << "\ngsave\n"; |
499 if(_scale!=1.0) os << _scale << " dup scale\n"; |
515 if(_scaleToA4) |
|
516 if(bb.height()>bb.width()) { |
|
517 double sc= min((A4HEIGHT-2*A4BORDER)/bb.height(), |
|
518 (A4WIDTH-2*A4BORDER)/bb.width()); |
|
519 os << ((A4WIDTH -2*A4BORDER)-sc*bb.width())/2 + A4BORDER << ' ' |
|
520 << ((A4HEIGHT-2*A4BORDER)-sc*bb.height())/2 + A4BORDER << " translate\n" |
|
521 << sc << " dup scale\n" |
|
522 << -bb.left() << ' ' << -bb.bottom() << " translate\n"; |
|
523 } |
|
524 else { |
|
525 //\todo Verify centering |
|
526 double sc= min((A4HEIGHT-2*A4BORDER)/bb.width(), |
|
527 (A4WIDTH-2*A4BORDER)/bb.height()); |
|
528 os << ((A4WIDTH -2*A4BORDER)-sc*bb.height())/2 + A4BORDER << ' ' |
|
529 << ((A4HEIGHT-2*A4BORDER)-sc*bb.width())/2 + A4BORDER << " translate\n" |
|
530 << sc << " dup scale\n90 rotate\n" |
|
531 << -bb.left() << ' ' << -bb.top() << " translate\n"; |
|
532 } |
|
533 else if(_scale!=1.0) os << _scale << " dup scale\n"; |
500 |
534 |
501 if(_showEdges) { |
535 if(_showEdges) { |
502 os << "%Edges:\ngsave\n"; |
536 os << "%Edges:\ngsave\n"; |
503 if(_enableParallel) { |
537 if(_enableParallel) { |
504 std::vector<Edge> el; |
538 std::vector<Edge> el; |
695 GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g,os)); |
729 GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g,os)); |
696 } |
730 } |
697 |
731 |
698 ///Generates an EPS file from a graph |
732 ///Generates an EPS file from a graph |
699 |
733 |
700 //\ingroup misc |
734 ///\ingroup misc |
701 ///This function does the same as |
735 ///This function does the same as |
702 ///\ref graphToEps(G &g,std::ostream& os) |
736 ///\ref graphToEps(G &g,std::ostream& os) |
703 ///but it writes its output into the file \c file_name |
737 ///but it writes its output into the file \c file_name |
704 ///instead of a stream. |
738 ///instead of a stream. |
705 ///\sa graphToEps(G &g, std::ostream& os) |
739 ///\sa graphToEps(G &g, std::ostream& os) |