Index: src/lemon/graph_to_eps.h
===================================================================
--- src/lemon/graph_to_eps.h	(revision 1164)
+++ src/lemon/graph_to_eps.h	(revision 1178)
@@ -52,13 +52,115 @@
   Color(double r,double g,double b) :_r(r),_g(g),_b(b) {};
   ///Returns the red component
-  double getR() {return _r;}
+
+  ///\todo \c red() could be a better name...
+  double getR() const {return _r;}
   ///Returns the green component
-  double getG() {return _g;}
+  double getG() const {return _g;}
   ///Returns the blue component
-  double getB() {return _b;}
+  double getB() const {return _b;}
   ///Set the color components
   void set(double r,double g,double b) { _r=r;_g=g;_b=b; };
 };
-  
+
+///Maps <tt>int</tt>s to different \ref Color "Color"s
+
+///This map assing one of the predefined \ref Color "Color"s
+///to each <tt>int</tt>. It is possible to change the colors as well as their
+///number. The integer range is cyclically mapped to the provided set of colors.
+///
+///This is a true \ref concept::ReferenceMap "reference map", so you can also
+///change the actual colors.
+
+class ColorSet : public MapBase<int,Color>
+{
+  std::vector<Color> colors;
+public:
+  ///Constructor
+
+  ///Constructor
+  ///\param have_white indicates wheter white is
+  ///amongst the provided color (\c true) or not (\c false). If it is true,
+  ///white will be assigned to \c 0.
+  ///\param num the number of the allocated colors. If it is \c 0
+  ///the default color configuration is set up (26 color plus the while).
+  ///If \c num is less then 26/27 then the default color list is cut. Otherwise
+  ///the color list is filled repeatedly with the default color list.
+  ColorSet(bool have_white=false,int num=0)
+  {
+    do {
+      if(have_white) colors.push_back(Color(1,1,1));
+
+      colors.push_back(Color(0,0,0));
+      colors.push_back(Color(1,0,0));
+      colors.push_back(Color(0,1,0));
+      colors.push_back(Color(0,0,1));
+      colors.push_back(Color(1,1,0));
+      colors.push_back(Color(1,0,1));
+      colors.push_back(Color(0,1,1));
+      
+      colors.push_back(Color(.5,0,0));
+      colors.push_back(Color(0,.5,0));
+      colors.push_back(Color(0,0,.5));
+      colors.push_back(Color(.5,.5,0));
+      colors.push_back(Color(.5,0,.5));
+      colors.push_back(Color(0,.5,.5));
+      
+      colors.push_back(Color(.5,.5,.5));
+      colors.push_back(Color(1,.5,.5));
+      colors.push_back(Color(.5,1,.5));
+      colors.push_back(Color(.5,.5,1));
+      colors.push_back(Color(1,1,.5));
+      colors.push_back(Color(1,.5,1));
+      colors.push_back(Color(.5,1,1));
+      
+      colors.push_back(Color(1,.5,0));
+      colors.push_back(Color(.5,1,0));
+      colors.push_back(Color(1,0,.5));
+      colors.push_back(Color(0,1,.5));
+      colors.push_back(Color(0,.5,1));
+      colors.push_back(Color(.5,0,1));
+    } while(int(colors.size())<num);
+    //    colors.push_back(Color(1,1,1));
+    if(num>0) colors.resize(num);
+  }
+  ///\e
+  Color &operator[](int i)
+  {
+    return colors[i%colors.size()];
+  }
+  ///\e
+  const Color &operator[](int i) const
+  {
+    return colors[i%colors.size()];
+  }
+  ///\e
+  void set(int i,const Color &c)
+  {
+    colors[i%colors.size()]=c;
+  }
+  ///Sets the number of the exiting colors.
+  void resize(int s) { colors.resize(s);}
+  ///Returns the munber of the existing colors.
+  std::size_t size() { return colors.size();}
+};
+
+///Returns a visible distinct \ref Color
+
+///Returns a \ref Color which is as different from the given parameter
+///as it is possible.
+inline Color distantColor(const Color &c) 
+{
+  return Color(c.getR()<.5?1:0,c.getG()<.5?1:0,c.getB()<.5?1:0);
+}
+///Returns black for light colors and white for the dark ones.
+
+///Returns black for light colors and white for the dark ones.
+///\todo weighted average would be better
+inline Color distantBW(const Color &c){
+  double v=(c.getR()+c.getR()+c.getR())<1.5?1:0;
+  
+  return Color(v,v,v);
+}
+
 ///Default traits class of \ref GraphToEps
 
@@ -126,5 +228,9 @@
   std::string _title;
   std::string _copyright;
-  
+
+  enum NodeTextColorType 
+    { DIST_COL=0, DIST_BW=1, CUST_COL=2, SAME_COL=3 } _nodeTextColorType;
+  ConstMap<typename Graph::Node,Color > _nodeTextColors;
+
   ///Constructor
 
@@ -150,5 +256,7 @@
     _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0),
     _undir(false),
-    _pleaseRemoveOsStream(_pros), _scaleToA4(false) {}
+    _pleaseRemoveOsStream(_pros), _scaleToA4(false),
+    _nodeTextColorType(SAME_COL), _nodeTextColors(Color(0,0,0))
+  {}
 };
 
@@ -224,9 +332,15 @@
     return xy<double>(v.y,-v.x);
   }
-  template<class xy>
-  static std::string psOut(const xy &p) 
+  template<class TT>
+  static std::string psOut(const xy<TT> &p) 
     {
       std::ostringstream os;	
       os << p.x << ' ' << p.y;
+      return os.str();
+    }
+  static std::string psOut(const Color &c) 
+    {
+      std::ostringstream os;	
+      os << c.getR() << ' ' << c.getG() << ' ' << c.getB();
       return os.str();
     }
@@ -345,4 +459,20 @@
     return GraphToEps<NodeColorsTraits<X> >(NodeColorsTraits<X>(*this,x));
   }
+  template<class X> struct NodeTextColorsTraits : public T {
+    const X &_nodeTextColors;
+    NodeTextColorsTraits(const T &t,const X &x) : T(t), _nodeTextColors(x) {}
+  };
+  ///Sets the map of the node text colors
+
+  ///Sets the map of the node text colors
+  ///\param x must be a node map with \ref Color values. 
+  template<class X> GraphToEps<NodeTextColorsTraits<X> >
+  nodeTextColors(const X &x)
+  {
+    dontPrint=true;
+    _nodeTextColorType=CUST_COL;
+    return GraphToEps<NodeTextColorsTraits<X> >
+      (NodeTextColorsTraits<X>(*this,x));
+  }
   template<class X> struct EdgeColorsTraits : public T {
     const X &_edgeColors;
@@ -436,4 +566,21 @@
   ///
   GraphToEps<T> &nodeTextSize(double d) {_nodeTextSize=d;return *this;}
+
+  ///Sets the color of the node texts to be different from the node color
+
+  ///Sets the color of the node texts to be as different from the node color
+  ///as it is possible
+    ///
+  GraphToEps<T> &distantColorNodeTexts()
+  {_nodeTextColorType=DIST_COL;return *this;}
+  ///Sets the color of the node texts to be black or white and always visible.
+
+  ///Sets the color of the node texts to be black or white according to
+  ///which is more 
+  ///different from the node color
+  ///
+  GraphToEps<T> &distantBWNodeTexts()
+  {_nodeTextColorType=DIST_BW;return *this;}
+
   ///Gives a preamble block for node Postscript block.
   
@@ -601,5 +748,6 @@
 	std::vector<Edge> el;
 	for(EdgeIt e(g);e!=INVALID;++e)
-	  if(!_undir||g.source(e)<g.target(e)) el.push_back(e);
+	  if((!_undir||g.source(e)<g.target(e))&&_edgeWidths[e]>0)
+	    el.push_back(e);
 	sort(el.begin(),el.end(),edgeLess(g));
 	
@@ -687,5 +835,5 @@
       }
       else for(EdgeIt e(g);e!=INVALID;++e)
-	if(!_undir||g.source(e)<g.target(e))
+	if((!_undir||g.source(e)<g.target(e))&&_edgeWidths[e]>0)
 	  if(_drawArrows) {
 	    xy<double> d(_coords[g.target(e)]-_coords[g.source(e)]);
@@ -742,8 +890,21 @@
       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)
+      for(NodeIt n(g);n!=INVALID;++n) {
+	switch(_nodeTextColorType) {
+	case DIST_COL:
+	  os << psOut(distantColor(_nodeColors[n])) << " setrgbcolor\n";
+	  break;
+	case DIST_BW:
+	  os << psOut(distantBW(_nodeColors[n])) << " setrgbcolor\n";
+	  break;
+	case CUST_COL:
+	  os << psOut(distantColor(_nodeTextColors[n])) << " setrgbcolor\n";
+	  break;
+	default:
+	  os << "0 0 0 setrgbcolor\n";
+	}
 	os << _coords[n].x << ' ' << _coords[n].y
 	   << " (" << _nodeTexts[n] << ") cshow\n";
+      }
       os << "grestore\n";
     }
@@ -777,5 +938,5 @@
 ///example shows how to use these parameters.
 ///\code
-/// graphToEps(g).scale(10).coords(coords)
+/// graphToEps(g,os).scale(10).coords(coords)
 ///              .nodeScale(2).nodeSizes(sizes)
 ///              .edgeWidthScale(.4).run();
