src/lemon/graph_to_eps.h
changeset 1106 0a7d604a9763
parent 1091 c756973cd53c
child 1107 d972653c89d5
equal deleted inserted replaced
6:a5af171c76a5 7:a30c8963de57
    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;
   656 	os << _coords[n].x << ' ' << _coords[n].y
   690 	os << _coords[n].x << ' ' << _coords[n].y
   657 	   << " moveto\n" << _nodePsTexts[n] << "\n";
   691 	   << " moveto\n" << _nodePsTexts[n] << "\n";
   658       os << "grestore\n";
   692       os << "grestore\n";
   659     }
   693     }
   660     
   694     
   661     os << "grestore\n";
   695     os << "grestore\nshowpage\n";
   662 
   696 
   663     //CleanUp:
   697     //CleanUp:
   664     if(_pleaseRemoveOsStream) {delete &os;}
   698     if(_pleaseRemoveOsStream) {delete &os;}
   665   } 
   699   } 
   666 };
   700 };
   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)