diff -r e41c2907fb49 -r 3c176c65d33b src/lemon/graph_to_eps.h --- a/src/lemon/graph_to_eps.h Thu Feb 24 17:48:25 2005 +0000 +++ b/src/lemon/graph_to_eps.h Fri Feb 25 14:50:22 2005 +0000 @@ -51,15 +51,117 @@ ///Constructor 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 ints to different \ref Color "Color"s + +///This map assing one of the predefined \ref Color "Color"s +///to each int. 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 +{ + std::vector 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())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 ///Default traits class of \ref GraphToEps @@ -125,7 +227,11 @@ std::string _title; std::string _copyright; - + + enum NodeTextColorType + { DIST_COL=0, DIST_BW=1, CUST_COL=2, SAME_COL=3 } _nodeTextColorType; + ConstMap _nodeTextColors; + ///Constructor ///Constructor @@ -149,7 +255,9 @@ _showNodeText(false), _nodeTexts(false), _nodeTextSize(1), _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0), _undir(false), - _pleaseRemoveOsStream(_pros), _scaleToA4(false) {} + _pleaseRemoveOsStream(_pros), _scaleToA4(false), + _nodeTextColorType(SAME_COL), _nodeTextColors(Color(0,0,0)) + {} }; ///Helper class to implement the named parameters of \ref graphToEps() @@ -223,13 +331,19 @@ { return xy(v.y,-v.x); } - template - static std::string psOut(const xy &p) + template + static std::string psOut(const xy &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(); + } public: GraphToEps(const T &t) : T(t), dontPrint(false) {}; @@ -344,6 +458,22 @@ dontPrint=true; return GraphToEps >(NodeColorsTraits(*this,x)); } + template 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 GraphToEps > + nodeTextColors(const X &x) + { + dontPrint=true; + _nodeTextColorType=CUST_COL; + return GraphToEps > + (NodeTextColorsTraits(*this,x)); + } template struct EdgeColorsTraits : public T { const X &_edgeColors; EdgeColorsTraits(const T &t,const X &x) : T(t), _edgeColors(x) {} @@ -435,6 +565,23 @@ ///Sets the size of the node texts /// GraphToEps &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 &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 &distantBWNodeTexts() + {_nodeTextColorType=DIST_BW;return *this;} + ///Gives a preamble block for node Postscript block. ///Gives a preamble block for node Postscript block. @@ -600,7 +747,8 @@ if(_enableParallel) { std::vector el; for(EdgeIt e(g);e!=INVALID;++e) - if(!_undir||g.source(e)0) + el.push_back(e); sort(el.begin(),el.end(),edgeLess(g)); typename std::vector::iterator j; @@ -686,7 +834,7 @@ } } else for(EdgeIt e(g);e!=INVALID;++e) - if(!_undir||g.source(e)0) if(_drawArrows) { xy d(_coords[g.target(e)]-_coords[g.source(e)]); double rn=_nodeSizes[g.target(e)]*_nodeScale; @@ -741,10 +889,23 @@ 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) + 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"; } if(_showNodePsText) { @@ -776,7 +937,7 @@ ///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) +/// graphToEps(g,os).scale(10).coords(coords) /// .nodeScale(2).nodeSizes(sizes) /// .edgeWidthScale(.4).run(); ///\endcode