gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Improvements related to graphToEps()
0 3 0
default
3 files changed with 98 insertions and 160 deletions:
↑ Collapse diff ↑
Ignore white space 96 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
/// \ingroup demos
20 20
/// \file
21
/// \brief Demo of the graph grawing function \ref graphToEps()
21
/// \brief Demo of the graph drawing function \ref graphToEps()
22 22
///
23 23
/// This demo program shows examples how to  use the function \ref
24 24
/// graphToEps(). It takes no input but simply creates  six
25 25
/// <tt>.eps</tt> files demonstrating the capability of \ref
26
/// graphToEps(), and showing how to draw directed/graphs,
26
/// graphToEps(), and showing how to draw directed graphs,
27 27
/// how to handle parallel egdes, how to change the properties (like
28 28
/// color, shape, size, title etc.) of nodes and arcs individually
29 29
/// using appropriate \ref maps-page "graph maps".
30 30
///
31 31
/// \include graph_to_eps_demo.cc
32 32

	
33
#include <lemon/math.h>
34

	
35
#include<lemon/graph_to_eps.h>
36 33
#include<lemon/list_graph.h>
37 34
#include<lemon/graph_utils.h>
35
#include<lemon/graph_to_eps.h>
36
#include<lemon/math.h>
38 37

	
39 38
using namespace std;
40 39
using namespace lemon;
41 40

	
42 41
int main()
43 42
{
44 43
  Palette palette;
45 44
  Palette paletteW(true);
46 45

	
46
  // Create a small digraph
47 47
  ListDigraph g;
48 48
  typedef ListDigraph::Node Node;
49 49
  typedef ListDigraph::NodeIt NodeIt;
50 50
  typedef ListDigraph::Arc Arc;
51 51
  typedef dim2::Point<int> Point;
52 52
  
53 53
  Node n1=g.addNode();
54 54
  Node n2=g.addNode();
55 55
  Node n3=g.addNode();
56 56
  Node n4=g.addNode();
57 57
  Node n5=g.addNode();
58 58

	
59 59
  ListDigraph::NodeMap<Point> coords(g);
60 60
  ListDigraph::NodeMap<double> sizes(g);
61 61
  ListDigraph::NodeMap<int> colors(g);
62 62
  ListDigraph::NodeMap<int> shapes(g);
63
  ListDigraph::ArcMap<int> ecolors(g);
63
  ListDigraph::ArcMap<int> acolors(g);
64 64
  ListDigraph::ArcMap<int> widths(g);
65 65
  
66 66
  coords[n1]=Point(50,50);  sizes[n1]=1; colors[n1]=1; shapes[n1]=0;
67 67
  coords[n2]=Point(50,70);  sizes[n2]=2; colors[n2]=2; shapes[n2]=2;
68 68
  coords[n3]=Point(70,70);  sizes[n3]=1; colors[n3]=3; shapes[n3]=0;
69 69
  coords[n4]=Point(70,50);  sizes[n4]=2; colors[n4]=4; shapes[n4]=1;
70 70
  coords[n5]=Point(85,60);  sizes[n5]=3; colors[n5]=5; shapes[n5]=2;
71 71
  
72
  Arc e;
72
  Arc a;
73 73

	
74
  e=g.addArc(n1,n2); ecolors[e]=0; widths[e]=1;
75
  e=g.addArc(n2,n3); ecolors[e]=0; widths[e]=1;
76
  e=g.addArc(n3,n5); ecolors[e]=0; widths[e]=3;
77
  e=g.addArc(n5,n4); ecolors[e]=0; widths[e]=1;
78
  e=g.addArc(n4,n1); ecolors[e]=0; widths[e]=1;
79
  e=g.addArc(n2,n4); ecolors[e]=1; widths[e]=2;
80
  e=g.addArc(n3,n4); ecolors[e]=2; widths[e]=1;
74
  a=g.addArc(n1,n2); acolors[a]=0; widths[a]=1;
75
  a=g.addArc(n2,n3); acolors[a]=0; widths[a]=1;
76
  a=g.addArc(n3,n5); acolors[a]=0; widths[a]=3;
77
  a=g.addArc(n5,n4); acolors[a]=0; widths[a]=1;
78
  a=g.addArc(n4,n1); acolors[a]=0; widths[a]=1;
79
  a=g.addArc(n2,n4); acolors[a]=1; widths[a]=2;
80
  a=g.addArc(n3,n4); acolors[a]=2; widths[a]=1;
81 81
  
82 82
  IdMap<ListDigraph,Node> id(g);
83 83

	
84
  cout << "Create 'graph_to_eps_demo_out_pure.eps'" << endl;
85
  graphToEps(g,"graph_to_eps_demo_out_pure.eps").
86
    //scale(10).
84
  // Create five .eps files showing the digraph with different options
85
  cout << "Create 'graph_to_eps_demo_out_1_pure.eps'" << endl;
86
  graphToEps(g,"graph_to_eps_demo_out_1_pure.eps").
87 87
    coords(coords).
88 88
    title("Sample .eps figure").
89
    copyright("(C) 2003-2007 LEMON Project").
89
    copyright("(C) 2003-2008 LEMON Project").
90 90
    run();
91 91

	
92
  cout << "Create 'graph_to_eps_demo_out.eps'" << endl;
93
  graphToEps(g,"graph_to_eps_demo_out.eps").
94
    //scale(10).
92
  cout << "Create 'graph_to_eps_demo_out_2.eps'" << endl;
93
  graphToEps(g,"graph_to_eps_demo_out_2.eps").
95 94
    coords(coords).
96 95
    title("Sample .eps figure").
97
    copyright("(C) 2003-2007 LEMON Project").
96
    copyright("(C) 2003-2008 LEMON Project").
98 97
    absoluteNodeSizes().absoluteArcWidths().
99 98
    nodeScale(2).nodeSizes(sizes).
100 99
    nodeShapes(shapes).
101 100
    nodeColors(composeMap(palette,colors)).
102
    arcColors(composeMap(palette,ecolors)).
101
    arcColors(composeMap(palette,acolors)).
103 102
    arcWidthScale(.4).arcWidths(widths).
104 103
    nodeTexts(id).nodeTextSize(3).
105 104
    run();
106 105

	
107

	
108
  cout << "Create 'graph_to_eps_demo_out_arr.eps'" << endl;
109
  graphToEps(g,"graph_to_eps_demo_out_arr.eps").
110
    //scale(10).
106
  cout << "Create 'graph_to_eps_demo_out_3_arr.eps'" << endl;
107
  graphToEps(g,"graph_to_eps_demo_out_3_arr.eps").
111 108
    title("Sample .eps figure (with arrowheads)").
112
    copyright("(C) 2003-2007 LEMON Project").
109
    copyright("(C) 2003-2008 LEMON Project").
113 110
    absoluteNodeSizes().absoluteArcWidths().
114 111
    nodeColors(composeMap(palette,colors)).
115 112
    coords(coords).
116 113
    nodeScale(2).nodeSizes(sizes).
117 114
    nodeShapes(shapes).
118
    arcColors(composeMap(palette,ecolors)).
115
    arcColors(composeMap(palette,acolors)).
119 116
    arcWidthScale(.4).arcWidths(widths).
120 117
    nodeTexts(id).nodeTextSize(3).
121
    drawArrows().arrowWidth(1).arrowLength(1).
118
    drawArrows().arrowWidth(2).arrowLength(2).
122 119
    run();
123 120

	
124
  e=g.addArc(n1,n4); ecolors[e]=2; widths[e]=1;
125
  e=g.addArc(n4,n1); ecolors[e]=1; widths[e]=2;
121
  a=g.addArc(n1,n4); acolors[a]=2; widths[a]=1;
122
  a=g.addArc(n4,n1); acolors[a]=1; widths[a]=2;
126 123

	
127
  e=g.addArc(n1,n2); ecolors[e]=1; widths[e]=1;
128
  e=g.addArc(n1,n2); ecolors[e]=2; widths[e]=1;
129
  e=g.addArc(n1,n2); ecolors[e]=3; widths[e]=1;
130
  e=g.addArc(n1,n2); ecolors[e]=4; widths[e]=1;
131
  e=g.addArc(n1,n2); ecolors[e]=5; widths[e]=1;
132
  e=g.addArc(n1,n2); ecolors[e]=6; widths[e]=1;
133
  e=g.addArc(n1,n2); ecolors[e]=7; widths[e]=1;
124
  a=g.addArc(n1,n2); acolors[a]=1; widths[a]=1;
125
  a=g.addArc(n1,n2); acolors[a]=2; widths[a]=1;
126
  a=g.addArc(n1,n2); acolors[a]=3; widths[a]=1;
127
  a=g.addArc(n1,n2); acolors[a]=4; widths[a]=1;
128
  a=g.addArc(n1,n2); acolors[a]=5; widths[a]=1;
129
  a=g.addArc(n1,n2); acolors[a]=6; widths[a]=1;
130
  a=g.addArc(n1,n2); acolors[a]=7; widths[a]=1;
134 131

	
135 132
  cout << "Create 'graph_to_eps_demo_out_par.eps'" << endl;
136 133
  graphToEps(g,"graph_to_eps_demo_out_par.eps").
137 134
    //scale(10).
138 135
    title("Sample .eps figure (parallel arcs)").
139
    copyright("(C) 2003-2007 LEMON Project").
136
    copyright("(C) 2003-2008 LEMON Project").
140 137
    absoluteNodeSizes().absoluteArcWidths().
141 138
    nodeShapes(shapes).
142 139
    coords(coords).
143 140
    nodeScale(2).nodeSizes(sizes).
144 141
    nodeColors(composeMap(palette,colors)).
145
    arcColors(composeMap(palette,ecolors)).
142
    arcColors(composeMap(palette,acolors)).
146 143
    arcWidthScale(.4).arcWidths(widths).
147 144
    nodeTexts(id).nodeTextSize(3).
148 145
    enableParallel().parArcDist(1.5).
149 146
    run();
150
  
151
  cout << "Create 'graph_to_eps_demo_out_par_arr.eps'" << endl;
152
  graphToEps(g,"graph_to_eps_demo_out_par_arr.eps").
153
    //scale(10).
147

	
148
  cout << "Create 'graph_to_eps_demo_out_4_par_arr.eps'" << endl;
149
  graphToEps(g,"graph_to_eps_demo_out_4_par_arr.eps").
154 150
    title("Sample .eps figure (parallel arcs and arrowheads)").
155
    copyright("(C) 2003-2007 LEMON Project").
151
    copyright("(C) 2003-2008 LEMON Project").
156 152
    absoluteNodeSizes().absoluteArcWidths().
157 153
    nodeScale(2).nodeSizes(sizes).
158 154
    coords(coords).
159 155
    nodeShapes(shapes).
160 156
    nodeColors(composeMap(palette,colors)).
161
    arcColors(composeMap(palette,ecolors)).
157
    arcColors(composeMap(palette,acolors)).
162 158
    arcWidthScale(.3).arcWidths(widths).
163 159
    nodeTexts(id).nodeTextSize(3).
164 160
    enableParallel().parArcDist(1).
165 161
    drawArrows().arrowWidth(1).arrowLength(1).
166 162
    run();
167 163

	
168
  cout << "Create 'graph_to_eps_demo_out_a4.eps'" << endl;
169
  graphToEps(g,"graph_to_eps_demo_out_a4.eps").scaleToA4().
164
  cout << "Create 'graph_to_eps_demo_out_5_par_arr_a4.eps'" << endl;
165
  graphToEps(g,"graph_to_eps_demo_out_5_par_arr_a4.eps").
170 166
    title("Sample .eps figure (fits to A4)").
171
    copyright("(C) 2003-2007 LEMON Project").
167
    copyright("(C) 2003-2008 LEMON Project").
168
    scaleToA4().
172 169
    absoluteNodeSizes().absoluteArcWidths().
173 170
    nodeScale(2).nodeSizes(sizes).
174 171
    coords(coords).
175 172
    nodeShapes(shapes).
176 173
    nodeColors(composeMap(palette,colors)).
177
    arcColors(composeMap(palette,ecolors)).
174
    arcColors(composeMap(palette,acolors)).
178 175
    arcWidthScale(.3).arcWidths(widths).
179 176
    nodeTexts(id).nodeTextSize(3).
180 177
    enableParallel().parArcDist(1).
181 178
    drawArrows().arrowWidth(1).arrowLength(1).
182 179
    run();
183 180

	
181
  // Create an .eps file showing the colors of a default Palette
184 182
  ListDigraph h;
185 183
  ListDigraph::NodeMap<int> hcolors(h);
186 184
  ListDigraph::NodeMap<Point> hcoords(h);
187 185
  
188 186
  int cols=int(sqrt(double(palette.size())));
189 187
  for(int i=0;i<int(paletteW.size());i++) {
190 188
    Node n=h.addNode();
191
    hcoords[n]=Point(i%cols,i/cols);
189
    hcoords[n]=Point(1+i%cols,1+i/cols);
192 190
    hcolors[n]=i;
193 191
  }
194 192
  
195
  cout << "Create 'graph_to_eps_demo_out_colors.eps'" << endl;
196
  graphToEps(h,"graph_to_eps_demo_out_colors.eps").
197
    //scale(60).
193
  cout << "Create 'graph_to_eps_demo_out_6_colors.eps'" << endl;
194
  graphToEps(h,"graph_to_eps_demo_out_6_colors.eps").
195
    scale(60).
198 196
    title("Sample .eps figure (Palette demo)").
199
    copyright("(C) 2003-2007 LEMON Project").
197
    copyright("(C) 2003-2008 LEMON Project").
200 198
    coords(hcoords).
201 199
    absoluteNodeSizes().absoluteArcWidths().
202 200
    nodeScale(.45).
203 201
    distantColorNodeTexts().
204
    //    distantBWNodeTexts().
205 202
    nodeTexts(hcolors).nodeTextSize(.6).
206 203
    nodeColors(composeMap(paletteW,hcolors)).
207 204
    run();
205
    
206
  return 0;
208 207
}
Ignore white space 6 line context
... ...
@@ -63,143 +63,142 @@
63 63

	
64 64
  /// White color constant
65 65
  extern const Color WHITE;  
66 66
  /// Black color constant
67 67
  extern const Color BLACK;
68 68
  /// Red color constant
69 69
  extern const Color RED;
70 70
  /// Green color constant
71 71
  extern const Color GREEN;
72 72
  /// Blue color constant
73 73
  extern const Color BLUE;
74 74
  /// Yellow color constant
75 75
  extern const Color YELLOW;
76 76
  /// Magenta color constant
77 77
  extern const Color MAGENTA;
78 78
  /// Cyan color constant
79 79
  extern const Color CYAN;
80 80
  /// Grey color constant
81 81
  extern const Color GREY;
82 82
  /// Dark red color constant
83 83
  extern const Color DARK_RED;
84 84
  /// Dark green color constant
85 85
  extern const Color DARK_GREEN;
86 86
  /// Drak blue color constant
87 87
  extern const Color DARK_BLUE;
88 88
  /// Dark yellow color constant
89 89
  extern const Color DARK_YELLOW;
90 90
  /// Dark magenta color constant
91 91
  extern const Color DARK_MAGENTA;
92 92
  /// Dark cyan color constant
93 93
  extern const Color DARK_CYAN;
94 94

	
95 95
  ///Map <tt>int</tt>s to different \ref Color "Color"s
96 96

	
97 97
  ///This map assigns one of the predefined \ref Color "Color"s to
98 98
  ///each <tt>int</tt>. It is possible to change the colors as well as
99 99
  ///their number. The integer range is cyclically mapped to the
100 100
  ///provided set of colors.
101 101
  ///
102 102
  ///This is a true \ref concepts::ReferenceMap "reference map", so
103 103
  ///you can also change the actual colors.
104 104

	
105 105
  class Palette : public MapBase<int,Color>
106 106
  {
107 107
    std::vector<Color> colors;
108 108
  public:
109 109
    ///Constructor
110 110

	
111
    ///Constructor 
112
    ///\param have_white indicates whether white is amongst the
111
    ///Constructor.
112
    ///\param have_white Indicates whether white is among the
113 113
    ///provided initial colors (\c true) or not (\c false). If it is true,
114 114
    ///white will be assigned to \c 0.
115
    ///\param num the number of the allocated colors. If it is \c -1,
115
    ///\param num The number of the allocated colors. If it is \c -1,
116 116
    ///the default color configuration is set up (26 color plus optionaly the
117 117
    ///white).  If \c num is less then 26/27 then the default color
118 118
    ///list is cut. Otherwise the color list is filled repeatedly with
119 119
    ///the default color list.  (The colors can be changed later on.)
120 120
    Palette(bool have_white=false,int num=-1)
121 121
    {
122 122
      if (num==0) return;
123 123
      do {
124 124
        if(have_white) colors.push_back(Color(1,1,1));
125 125

	
126 126
        colors.push_back(Color(0,0,0));
127 127
        colors.push_back(Color(1,0,0));
128 128
        colors.push_back(Color(0,1,0));
129 129
        colors.push_back(Color(0,0,1));
130 130
        colors.push_back(Color(1,1,0));
131 131
        colors.push_back(Color(1,0,1));
132 132
        colors.push_back(Color(0,1,1));
133 133
      
134 134
        colors.push_back(Color(.5,0,0));
135 135
        colors.push_back(Color(0,.5,0));
136 136
        colors.push_back(Color(0,0,.5));
137 137
        colors.push_back(Color(.5,.5,0));
138 138
        colors.push_back(Color(.5,0,.5));
139 139
        colors.push_back(Color(0,.5,.5));
140 140
      
141 141
        colors.push_back(Color(.5,.5,.5));
142 142
        colors.push_back(Color(1,.5,.5));
143 143
        colors.push_back(Color(.5,1,.5));
144 144
        colors.push_back(Color(.5,.5,1));
145 145
        colors.push_back(Color(1,1,.5));
146 146
        colors.push_back(Color(1,.5,1));
147 147
        colors.push_back(Color(.5,1,1));
148 148
      
149 149
        colors.push_back(Color(1,.5,0));
150 150
        colors.push_back(Color(.5,1,0));
151 151
        colors.push_back(Color(1,0,.5));
152 152
        colors.push_back(Color(0,1,.5));
153 153
        colors.push_back(Color(0,.5,1));
154 154
        colors.push_back(Color(.5,0,1));
155 155
      } while(int(colors.size())<num);
156
      //    colors.push_back(Color(1,1,1));
157 156
      if(num>=0) colors.resize(num);
158 157
    }
159 158
    ///\e
160 159
    Color &operator[](int i)
161 160
    {
162 161
      return colors[i%colors.size()];
163 162
    }
164 163
    ///\e
165 164
    const Color &operator[](int i) const
166 165
    {
167 166
      return colors[i%colors.size()];
168 167
    }
169 168
    ///\e
170 169
    void set(int i,const Color &c)
171 170
    {
172 171
      colors[i%colors.size()]=c;
173 172
    }
174
    ///Add a new color to the end of the color list.
173
    ///Adds a new color to the end of the color list.
175 174
    void add(const Color &c) 
176 175
    {
177 176
      colors.push_back(c);
178 177
    }
179 178

	
180
    ///Sets the number of the exiting colors.
179
    ///Sets the number of the existing colors.
181 180
    void resize(int s) { colors.resize(s);}
182 181
    ///Returns the number of the existing colors.
183 182
    int size() const { return int(colors.size());}
184 183
  };
185 184

	
186 185
  ///Returns a visibly distinct \ref Color
187 186

	
188 187
  ///Returns a \ref Color which is as different from the given parameter
189 188
  ///as it is possible.
190 189
  inline Color distantColor(const Color &c) 
191 190
  {
192 191
    return Color(c.red()<.5?1:0,c.green()<.5?1:0,c.blue()<.5?1:0);
193 192
  }
194 193
  ///Returns black for light colors and white for the dark ones.
195 194

	
196 195
  ///Returns black for light colors and white for the dark ones.
197 196
  inline Color distantBW(const Color &c){
198 197
    return (.2125*c.red()+.7154*c.green()+.0721*c.blue())<.5 ? WHITE : BLACK;
199 198
  }
200 199

	
201 200
  /// @}
202 201

	
203 202
} //END OF NAMESPACE LEMON
204 203

	
205 204
#endif // LEMON_COLOR_H
Ignore white space 6 line context
... ...
@@ -18,792 +18,750 @@
18 18

	
19 19
#ifndef LEMON_GRAPH_TO_EPS_H
20 20
#define LEMON_GRAPH_TO_EPS_H
21 21

	
22 22
#include<iostream>
23 23
#include<fstream>
24 24
#include<sstream>
25 25
#include<algorithm>
26 26
#include<vector>
27 27

	
28 28
#ifndef WIN32
29 29
#include<sys/time.h>
30 30
#include<ctime>
31 31
#else
32 32
#define WIN32_LEAN_AND_MEAN
33 33
#define NOMINMAX
34 34
#include<windows.h>
35 35
#endif
36 36

	
37 37
#include<lemon/math.h>
38 38
#include<lemon/bits/invalid.h>
39 39
#include<lemon/dim2.h>
40 40
#include<lemon/maps.h>
41 41
#include<lemon/color.h>
42 42
#include<lemon/bits/bezier.h>
43 43

	
44 44

	
45 45
///\ingroup eps_io
46 46
///\file
47 47
///\brief A well configurable tool for visualizing graphs
48 48

	
49 49
namespace lemon {
50 50

	
51 51
  namespace _graph_to_eps_bits {
52 52
    template<class MT>
53 53
    class _NegY {
54 54
    public:
55 55
      typedef typename MT::Key Key;
56 56
      typedef typename MT::Value Value;
57 57
      const MT &map;
58 58
      int yscale;
59 59
      _NegY(const MT &m,bool b) : map(m), yscale(1-b*2) {}
60 60
      Value operator[](Key n) { return Value(map[n].x,map[n].y*yscale);}
61 61
    };
62 62
  }
63 63
  
64 64
///Default traits class of \ref GraphToEps
65 65

	
66
///Default traits class of \ref GraphToEps
66
///Default traits class of \ref GraphToEps.
67 67
///
68 68
///\c G is the type of the underlying graph.
69 69
template<class G>
70 70
struct DefaultGraphToEpsTraits
71 71
{
72 72
  typedef G Graph;
73 73
  typedef typename Graph::Node Node;
74 74
  typedef typename Graph::NodeIt NodeIt;
75 75
  typedef typename Graph::Arc Arc;
76 76
  typedef typename Graph::ArcIt ArcIt;
77 77
  typedef typename Graph::InArcIt InArcIt;
78 78
  typedef typename Graph::OutArcIt OutArcIt;
79 79
  
80 80

	
81 81
  const Graph &g;
82 82

	
83 83
  std::ostream& os;
84 84
  
85 85
  typedef ConstMap<typename Graph::Node,dim2::Point<double> > CoordsMapType;
86 86
  CoordsMapType _coords;
87 87
  ConstMap<typename Graph::Node,double > _nodeSizes;
88 88
  ConstMap<typename Graph::Node,int > _nodeShapes;
89 89

	
90 90
  ConstMap<typename Graph::Node,Color > _nodeColors;
91 91
  ConstMap<typename Graph::Arc,Color > _arcColors;
92 92

	
93 93
  ConstMap<typename Graph::Arc,double > _arcWidths;
94 94

	
95 95
  double _arcWidthScale;
96 96
  
97 97
  double _nodeScale;
98 98
  double _xBorder, _yBorder;
99 99
  double _scale;
100 100
  double _nodeBorderQuotient;
101 101
  
102 102
  bool _drawArrows;
103 103
  double _arrowLength, _arrowWidth;
104 104
  
105 105
  bool _showNodes, _showArcs;
106 106

	
107 107
  bool _enableParallel;
108 108
  double _parArcDist;
109 109

	
110 110
  bool _showNodeText;
111 111
  ConstMap<typename Graph::Node,bool > _nodeTexts;  
112 112
  double _nodeTextSize;
113 113

	
114 114
  bool _showNodePsText;
115 115
  ConstMap<typename Graph::Node,bool > _nodePsTexts;  
116 116
  char *_nodePsTextsPreamble;
117 117
  
118 118
  bool _undirected;
119 119

	
120 120
  bool _pleaseRemoveOsStream;
121 121

	
122 122
  bool _scaleToA4;
123 123

	
124 124
  std::string _title;
125 125
  std::string _copyright;
126 126

	
127 127
  enum NodeTextColorType 
128 128
    { DIST_COL=0, DIST_BW=1, CUST_COL=2, SAME_COL=3 } _nodeTextColorType;
129 129
  ConstMap<typename Graph::Node,Color > _nodeTextColors;
130 130

	
131 131
  bool _autoNodeScale;
132 132
  bool _autoArcWidthScale;
133 133

	
134 134
  bool _absoluteNodeSizes;
135 135
  bool _absoluteArcWidths;
136 136

	
137 137
  bool _negY;
138 138

	
139 139
  bool _preScale;
140 140
  ///Constructor
141 141

	
142 142
  ///Constructor
143
  ///\param _g is a reference to the graph to be printed
144
  ///\param _os is a reference to the output stream.
145
  ///\param _os is a reference to the output stream.
143
  ///\param _g  Reference to the graph to be printed.
144
  ///\param _os Reference to the output stream.
145
  ///\param _os Reference to the output stream. By default it is <tt>std::cout</tt>.
146 146
  ///\param _pros If it is \c true, then the \c ostream referenced by \c _os
147 147
  ///will be explicitly deallocated by the destructor.
148
  ///By default it is <tt>std::cout</tt>
149 148
  DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout,
150 149
			  bool _pros=false) :
151 150
    g(_g), os(_os),
152 151
    _coords(dim2::Point<double>(1,1)), _nodeSizes(1), _nodeShapes(0),
153 152
    _nodeColors(WHITE), _arcColors(BLACK),
154 153
    _arcWidths(1.0), _arcWidthScale(0.003),
155 154
    _nodeScale(.01), _xBorder(10), _yBorder(10), _scale(1.0),
156 155
    _nodeBorderQuotient(.1),
157 156
    _drawArrows(false), _arrowLength(1), _arrowWidth(0.3),
158 157
    _showNodes(true), _showArcs(true),
159 158
    _enableParallel(false), _parArcDist(1),
160 159
    _showNodeText(false), _nodeTexts(false), _nodeTextSize(1),
161 160
    _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0),
162 161
    _undirected(lemon::UndirectedTagIndicator<G>::value),
163 162
    _pleaseRemoveOsStream(_pros), _scaleToA4(false),
164 163
    _nodeTextColorType(SAME_COL), _nodeTextColors(BLACK),
165 164
    _autoNodeScale(false),
166 165
    _autoArcWidthScale(false),
167 166
    _absoluteNodeSizes(false),
168 167
    _absoluteArcWidths(false),
169 168
    _negY(false),
170 169
    _preScale(true)
171 170
  {}
172 171
};
173 172

	
174 173
///Auxiliary class to implement the named parameters of \ref graphToEps()
175 174

	
176
///Auxiliary class to implement the named parameters of \ref graphToEps()
175
///Auxiliary class to implement the named parameters of \ref graphToEps().
176
///
177
///For detailed examples see the \ref graph_to_eps_demo.cc demo file.
177 178
template<class T> class GraphToEps : public T 
178 179
{
179 180
  // Can't believe it is required by the C++ standard
180 181
  using T::g;
181 182
  using T::os;
182 183

	
183 184
  using T::_coords;
184 185
  using T::_nodeSizes;
185 186
  using T::_nodeShapes;
186 187
  using T::_nodeColors;
187 188
  using T::_arcColors;
188 189
  using T::_arcWidths;
189 190

	
190 191
  using T::_arcWidthScale;
191 192
  using T::_nodeScale;
192 193
  using T::_xBorder;
193 194
  using T::_yBorder;
194 195
  using T::_scale;
195 196
  using T::_nodeBorderQuotient;
196 197
  
197 198
  using T::_drawArrows;
198 199
  using T::_arrowLength;
199 200
  using T::_arrowWidth;
200 201
  
201 202
  using T::_showNodes;
202 203
  using T::_showArcs;
203 204

	
204 205
  using T::_enableParallel;
205 206
  using T::_parArcDist;
206 207

	
207 208
  using T::_showNodeText;
208 209
  using T::_nodeTexts;  
209 210
  using T::_nodeTextSize;
210 211

	
211 212
  using T::_showNodePsText;
212 213
  using T::_nodePsTexts;  
213 214
  using T::_nodePsTextsPreamble;
214 215
  
215 216
  using T::_undirected;
216 217

	
217 218
  using T::_pleaseRemoveOsStream;
218 219

	
219 220
  using T::_scaleToA4;
220 221

	
221 222
  using T::_title;
222 223
  using T::_copyright;
223 224

	
224 225
  using T::NodeTextColorType;
225 226
  using T::CUST_COL;
226 227
  using T::DIST_COL;
227 228
  using T::DIST_BW;
228 229
  using T::_nodeTextColorType;
229 230
  using T::_nodeTextColors;
230 231

	
231 232
  using T::_autoNodeScale;
232 233
  using T::_autoArcWidthScale;
233 234

	
234 235
  using T::_absoluteNodeSizes;
235 236
  using T::_absoluteArcWidths;
236 237

	
237 238

	
238 239
  using T::_negY;
239 240
  using T::_preScale;
240 241

	
241 242
  // dradnats ++C eht yb deriuqer si ti eveileb t'naC
242 243

	
243 244
  typedef typename T::Graph Graph;
244 245
  typedef typename Graph::Node Node;
245 246
  typedef typename Graph::NodeIt NodeIt;
246 247
  typedef typename Graph::Arc Arc;
247 248
  typedef typename Graph::ArcIt ArcIt;
248 249
  typedef typename Graph::InArcIt InArcIt;
249 250
  typedef typename Graph::OutArcIt OutArcIt;
250 251

	
251 252
  static const int INTERPOL_PREC;
252 253
  static const double A4HEIGHT;
253 254
  static const double A4WIDTH;
254 255
  static const double A4BORDER;
255 256

	
256 257
  bool dontPrint;
257 258

	
258 259
public:
259 260
  ///Node shapes
260 261

	
261
  ///Node shapes
262
  ///Node shapes.
262 263
  ///
263 264
  enum NodeShapes { 
264 265
    /// = 0
265 266
    ///\image html nodeshape_0.png
266 267
    ///\image latex nodeshape_0.eps "CIRCLE shape (0)" width=2cm
267 268
    CIRCLE=0, 
268 269
    /// = 1
269 270
    ///\image html nodeshape_1.png
270 271
    ///\image latex nodeshape_1.eps "SQUARE shape (1)" width=2cm
271 272
    ///
272 273
    SQUARE=1, 
273 274
    /// = 2
274 275
    ///\image html nodeshape_2.png
275 276
    ///\image latex nodeshape_2.eps "DIAMOND shape (2)" width=2cm
276 277
    ///
277 278
    DIAMOND=2,
278 279
    /// = 3
279 280
    ///\image html nodeshape_3.png
280 281
    ///\image latex nodeshape_2.eps "MALE shape (4)" width=2cm
281 282
    ///
282 283
    MALE=3,
283 284
    /// = 4
284 285
    ///\image html nodeshape_4.png
285 286
    ///\image latex nodeshape_2.eps "FEMALE shape (4)" width=2cm
286 287
    ///
287 288
    FEMALE=4
288 289
  };
289 290

	
290 291
private:
291 292
  class arcLess {
292 293
    const Graph &g;
293 294
  public:
294 295
    arcLess(const Graph &_g) : g(_g) {}
295 296
    bool operator()(Arc a,Arc b) const 
296 297
    {
297 298
      Node ai=std::min(g.source(a),g.target(a));
298 299
      Node aa=std::max(g.source(a),g.target(a));
299 300
      Node bi=std::min(g.source(b),g.target(b));
300 301
      Node ba=std::max(g.source(b),g.target(b));
301 302
      return ai<bi ||
302 303
	(ai==bi && (aa < ba || 
303 304
		    (aa==ba && ai==g.source(a) && bi==g.target(b))));
304 305
    }
305 306
  };
306 307
  bool isParallel(Arc e,Arc f) const
307 308
  {
308 309
    return (g.source(e)==g.source(f)&&
309 310
	    g.target(e)==g.target(f)) ||
310 311
      (g.source(e)==g.target(f)&&
311 312
       g.target(e)==g.source(f));
312 313
  }
313 314
  template<class TT>
314 315
  static std::string psOut(const dim2::Point<TT> &p) 
315 316
    {
316 317
      std::ostringstream os;	
317 318
      os << p.x << ' ' << p.y;
318 319
      return os.str();
319 320
    }
320 321
  static std::string psOut(const Color &c) 
321 322
    {
322 323
      std::ostringstream os;	
323 324
      os << c.red() << ' ' << c.green() << ' ' << c.blue();
324 325
      return os.str();
325 326
    }
326 327
  
327 328
public:
328 329
  GraphToEps(const T &t) : T(t), dontPrint(false) {};
329 330
  
330 331
  template<class X> struct CoordsTraits : public T {
331 332
  typedef X CoordsMapType;
332 333
    const X &_coords;
333 334
    CoordsTraits(const T &t,const X &x) : T(t), _coords(x) {}
334 335
  };
335 336
  ///Sets the map of the node coordinates
336 337

	
337 338
  ///Sets the map of the node coordinates.
338
  ///\param x must be a node map with dim2::Point<double> or
339
  ///\param x must be a node map with \ref dim2::Point "dim2::Point<double>" or
339 340
  ///\ref dim2::Point "dim2::Point<int>" values. 
340 341
  template<class X> GraphToEps<CoordsTraits<X> > coords(const X &x) {
341 342
    dontPrint=true;
342 343
    return GraphToEps<CoordsTraits<X> >(CoordsTraits<X>(*this,x));
343 344
  }
344 345
  template<class X> struct NodeSizesTraits : public T {
345 346
    const X &_nodeSizes;
346 347
    NodeSizesTraits(const T &t,const X &x) : T(t), _nodeSizes(x) {}
347 348
  };
348 349
  ///Sets the map of the node sizes
349 350

	
350
  ///Sets the map of the node sizes
351
  ///Sets the map of the node sizes.
351 352
  ///\param x must be a node map with \c double (or convertible) values. 
352 353
  template<class X> GraphToEps<NodeSizesTraits<X> > nodeSizes(const X &x)
353 354
  {
354 355
    dontPrint=true;
355 356
    return GraphToEps<NodeSizesTraits<X> >(NodeSizesTraits<X>(*this,x));
356 357
  }
357 358
  template<class X> struct NodeShapesTraits : public T {
358 359
    const X &_nodeShapes;
359 360
    NodeShapesTraits(const T &t,const X &x) : T(t), _nodeShapes(x) {}
360 361
  };
361 362
  ///Sets the map of the node shapes
362 363

	
363 364
  ///Sets the map of the node shapes.
364 365
  ///The available shape values
365 366
  ///can be found in \ref NodeShapes "enum NodeShapes".
366 367
  ///\param x must be a node map with \c int (or convertible) values. 
367 368
  ///\sa NodeShapes
368 369
  template<class X> GraphToEps<NodeShapesTraits<X> > nodeShapes(const X &x)
369 370
  {
370 371
    dontPrint=true;
371 372
    return GraphToEps<NodeShapesTraits<X> >(NodeShapesTraits<X>(*this,x));
372 373
  }
373 374
  template<class X> struct NodeTextsTraits : public T {
374 375
    const X &_nodeTexts;
375 376
    NodeTextsTraits(const T &t,const X &x) : T(t), _nodeTexts(x) {}
376 377
  };
377 378
  ///Sets the text printed on the nodes
378 379

	
379
  ///Sets the text printed on the nodes
380
  ///Sets the text printed on the nodes.
380 381
  ///\param x must be a node map with type that can be pushed to a standard
381
  ///ostream. 
382
  ///\c ostream. 
382 383
  template<class X> GraphToEps<NodeTextsTraits<X> > nodeTexts(const X &x)
383 384
  {
384 385
    dontPrint=true;
385 386
    _showNodeText=true;
386 387
    return GraphToEps<NodeTextsTraits<X> >(NodeTextsTraits<X>(*this,x));
387 388
  }
388 389
  template<class X> struct NodePsTextsTraits : public T {
389 390
    const X &_nodePsTexts;
390 391
    NodePsTextsTraits(const T &t,const X &x) : T(t), _nodePsTexts(x) {}
391 392
  };
392 393
  ///Inserts a PostScript block to the nodes
393 394

	
394 395
  ///With this command it is possible to insert a verbatim PostScript
395 396
  ///block to the nodes.
396
  ///The PS current point will be moved to the centre of the node before
397
  ///The PS current point will be moved to the center of the node before
397 398
  ///the PostScript block inserted.
398 399
  ///
399 400
  ///Before and after the block a newline character is inserted so you
400 401
  ///don't have to bother with the separators.
401 402
  ///
402 403
  ///\param x must be a node map with type that can be pushed to a standard
403
  ///ostream.
404
  ///\c ostream.
404 405
  ///
405 406
  ///\sa nodePsTextsPreamble()
406 407
  template<class X> GraphToEps<NodePsTextsTraits<X> > nodePsTexts(const X &x)
407 408
  {
408 409
    dontPrint=true;
409 410
    _showNodePsText=true;
410 411
    return GraphToEps<NodePsTextsTraits<X> >(NodePsTextsTraits<X>(*this,x));
411 412
  }
412 413
  template<class X> struct ArcWidthsTraits : public T {
413 414
    const X &_arcWidths;
414 415
    ArcWidthsTraits(const T &t,const X &x) : T(t), _arcWidths(x) {}
415 416
  };
416 417
  ///Sets the map of the arc widths
417 418

	
418
  ///Sets the map of the arc widths
419
  ///Sets the map of the arc widths.
419 420
  ///\param x must be an arc map with \c double (or convertible) values. 
420 421
  template<class X> GraphToEps<ArcWidthsTraits<X> > arcWidths(const X &x)
421 422
  {
422 423
    dontPrint=true;
423 424
    return GraphToEps<ArcWidthsTraits<X> >(ArcWidthsTraits<X>(*this,x));
424 425
  }
425 426

	
426 427
  template<class X> struct NodeColorsTraits : public T {
427 428
    const X &_nodeColors;
428 429
    NodeColorsTraits(const T &t,const X &x) : T(t), _nodeColors(x) {}
429 430
  };
430 431
  ///Sets the map of the node colors
431 432

	
432
  ///Sets the map of the node colors
433
  ///Sets the map of the node colors.
433 434
  ///\param x must be a node map with \ref Color values.
434 435
  ///
435 436
  ///\sa Palette
436 437
  template<class X> GraphToEps<NodeColorsTraits<X> >
437 438
  nodeColors(const X &x)
438 439
  {
439 440
    dontPrint=true;
440 441
    return GraphToEps<NodeColorsTraits<X> >(NodeColorsTraits<X>(*this,x));
441 442
  }
442 443
  template<class X> struct NodeTextColorsTraits : public T {
443 444
    const X &_nodeTextColors;
444 445
    NodeTextColorsTraits(const T &t,const X &x) : T(t), _nodeTextColors(x) {}
445 446
  };
446 447
  ///Sets the map of the node text colors
447 448

	
448
  ///Sets the map of the node text colors
449
  ///Sets the map of the node text colors.
449 450
  ///\param x must be a node map with \ref Color values. 
450 451
  ///
451 452
  ///\sa Palette
452 453
  template<class X> GraphToEps<NodeTextColorsTraits<X> >
453 454
  nodeTextColors(const X &x)
454 455
  {
455 456
    dontPrint=true;
456 457
    _nodeTextColorType=CUST_COL;
457 458
    return GraphToEps<NodeTextColorsTraits<X> >
458 459
      (NodeTextColorsTraits<X>(*this,x));
459 460
  }
460 461
  template<class X> struct ArcColorsTraits : public T {
461 462
    const X &_arcColors;
462 463
    ArcColorsTraits(const T &t,const X &x) : T(t), _arcColors(x) {}
463 464
  };
464 465
  ///Sets the map of the arc colors
465 466

	
466
  ///Sets the map of the arc colors
467
  ///Sets the map of the arc colors.
467 468
  ///\param x must be an arc map with \ref Color values. 
468 469
  ///
469 470
  ///\sa Palette
470 471
  template<class X> GraphToEps<ArcColorsTraits<X> >
471 472
  arcColors(const X &x)
472 473
  {
473 474
    dontPrint=true;
474 475
    return GraphToEps<ArcColorsTraits<X> >(ArcColorsTraits<X>(*this,x));
475 476
  }
476 477
  ///Sets a global scale factor for node sizes
477 478

	
478 479
  ///Sets a global scale factor for node sizes.
479 480
  /// 
480 481
  /// If nodeSizes() is not given, this function simply sets the node
481 482
  /// sizes to \c d.  If nodeSizes() is given, but
482 483
  /// autoNodeScale() is not, then the node size given by
483 484
  /// nodeSizes() will be multiplied by the value \c d.
484 485
  /// If both nodeSizes() and autoNodeScale() are used, then the
485 486
  /// node sizes will be scaled in such a way that the greatest size will be
486 487
  /// equal to \c d.
487 488
  /// \sa nodeSizes()
488 489
  /// \sa autoNodeScale()
489 490
  GraphToEps<T> &nodeScale(double d=.01) {_nodeScale=d;return *this;}
490
  ///Turns on/off the automatic node width scaling.
491
  ///Turns on/off the automatic node size scaling.
491 492

	
492
  ///Turns on/off the automatic node width scaling.
493
  ///Turns on/off the automatic node size scaling.
493 494
  ///
494 495
  ///\sa nodeScale()
495 496
  ///
496 497
  GraphToEps<T> &autoNodeScale(bool b=true) {
497 498
    _autoNodeScale=b;return *this;
498 499
  }
499 500

	
500
  ///Turns on/off the absolutematic node width scaling.
501
  ///Turns on/off the absolutematic node size scaling.
501 502

	
502
  ///Turns on/off the absolutematic node width scaling.
503
  ///Turns on/off the absolutematic node size scaling.
503 504
  ///
504 505
  ///\sa nodeScale()
505 506
  ///
506 507
  GraphToEps<T> &absoluteNodeSizes(bool b=true) {
507 508
    _absoluteNodeSizes=b;return *this;
508 509
  }
509 510

	
510 511
  ///Negates the Y coordinates.
511

	
512
  ///Negates the Y coordinates.
513
  ///
514 512
  GraphToEps<T> &negateY(bool b=true) {
515 513
    _negY=b;return *this;
516 514
  }
517 515

	
518 516
  ///Turn on/off pre-scaling
519 517

	
520 518
  ///By default graphToEps() rescales the whole image in order to avoid
521 519
  ///very big or very small bounding boxes.
522 520
  ///
523 521
  ///This (p)rescaling can be turned off with this function.
524 522
  ///
525 523
  GraphToEps<T> &preScale(bool b=true) {
526 524
    _preScale=b;return *this;
527 525
  }
528 526

	
529 527
  ///Sets a global scale factor for arc widths
530 528

	
531 529
  /// Sets a global scale factor for arc widths.
532 530
  ///
533 531
  /// If arcWidths() is not given, this function simply sets the arc
534 532
  /// widths to \c d.  If arcWidths() is given, but
535 533
  /// autoArcWidthScale() is not, then the arc withs given by
536 534
  /// arcWidths() will be multiplied by the value \c d.
537 535
  /// If both arcWidths() and autoArcWidthScale() are used, then the
538 536
  /// arc withs will be scaled in such a way that the greatest width will be
539 537
  /// equal to \c d.
540 538
  GraphToEps<T> &arcWidthScale(double d=.003) {_arcWidthScale=d;return *this;}
541 539
  ///Turns on/off the automatic arc width scaling.
542 540

	
543 541
  ///Turns on/off the automatic arc width scaling.
544 542
  ///
545 543
  ///\sa arcWidthScale()
546 544
  ///
547 545
  GraphToEps<T> &autoArcWidthScale(bool b=true) {
548 546
    _autoArcWidthScale=b;return *this;
549 547
  }
550 548
  ///Turns on/off the absolutematic arc width scaling.
551 549

	
552 550
  ///Turns on/off the absolutematic arc width scaling.
553 551
  ///
554 552
  ///\sa arcWidthScale()
555 553
  ///
556 554
  GraphToEps<T> &absoluteArcWidths(bool b=true) {
557 555
    _absoluteArcWidths=b;return *this;
558 556
  }
559 557
  ///Sets a global scale factor for the whole picture
560

	
561
  ///Sets a global scale factor for the whole picture
562
  ///
563

	
564 558
  GraphToEps<T> &scale(double d) {_scale=d;return *this;}
565 559
  ///Sets the width of the border around the picture
566

	
567
  ///Sets the width of the border around the picture
568
  ///
569 560
  GraphToEps<T> &border(double b=10) {_xBorder=_yBorder=b;return *this;}
570 561
  ///Sets the width of the border around the picture
571

	
572
  ///Sets the width of the border around the picture
573
  ///
574 562
  GraphToEps<T> &border(double x, double y) {
575 563
    _xBorder=x;_yBorder=y;return *this;
576 564
  }
577 565
  ///Sets whether to draw arrows
578

	
579
  ///Sets whether to draw arrows
580
  ///
581 566
  GraphToEps<T> &drawArrows(bool b=true) {_drawArrows=b;return *this;}
582 567
  ///Sets the length of the arrowheads
583

	
584
  ///Sets the length of the arrowheads
585
  ///
586 568
  GraphToEps<T> &arrowLength(double d=1.0) {_arrowLength*=d;return *this;}
587 569
  ///Sets the width of the arrowheads
588

	
589
  ///Sets the width of the arrowheads
590
  ///
591 570
  GraphToEps<T> &arrowWidth(double d=.3) {_arrowWidth*=d;return *this;}
592 571
  
593 572
  ///Scales the drawing to fit to A4 page
594

	
595
  ///Scales the drawing to fit to A4 page
596
  ///
597 573
  GraphToEps<T> &scaleToA4() {_scaleToA4=true;return *this;}
598 574
  
599 575
  ///Enables parallel arcs
600

	
601
  ///Enables parallel arcs
602 576
  GraphToEps<T> &enableParallel(bool b=true) {_enableParallel=b;return *this;}
603 577
  
604
  ///Sets the distance 
605
  
606
  ///Sets the distance 
607
  ///
578
  ///Sets the distance between parallel arcs
608 579
  GraphToEps<T> &parArcDist(double d) {_parArcDist*=d;return *this;}
609 580
  
610 581
  ///Hides the arcs
611
  
612
  ///Hides the arcs
613
  ///
614 582
  GraphToEps<T> &hideArcs(bool b=true) {_showArcs=!b;return *this;}
615 583
  ///Hides the nodes
616
  
617
  ///Hides the nodes
618
  ///
619 584
  GraphToEps<T> &hideNodes(bool b=true) {_showNodes=!b;return *this;}
620 585
  
621 586
  ///Sets the size of the node texts
622
  
623
  ///Sets the size of the node texts
624
  ///
625 587
  GraphToEps<T> &nodeTextSize(double d) {_nodeTextSize=d;return *this;}
626 588

	
627 589
  ///Sets the color of the node texts to be different from the node color
628 590

	
629 591
  ///Sets the color of the node texts to be as different from the node color
630
  ///as it is possible
631
  ///
592
  ///as it is possible.
632 593
  GraphToEps<T> &distantColorNodeTexts()
633 594
  {_nodeTextColorType=DIST_COL;return *this;}
634 595
  ///Sets the color of the node texts to be black or white and always visible.
635 596

	
636 597
  ///Sets the color of the node texts to be black or white according to
637
  ///which is more 
638
  ///different from the node color
639
  ///
598
  ///which is more different from the node color.
640 599
  GraphToEps<T> &distantBWNodeTexts()
641 600
  {_nodeTextColorType=DIST_BW;return *this;}
642 601

	
643 602
  ///Gives a preamble block for node Postscript block.
644 603
  
645 604
  ///Gives a preamble block for node Postscript block.
646 605
  ///
647 606
  ///\sa nodePsTexts()
648 607
  GraphToEps<T> & nodePsTextsPreamble(const char *str) {
649 608
    _nodePsTextsPreamble=str ;return *this;
650 609
  }
651
  ///Sets whether the the graph is undirected
610
  ///Sets whether the graph is undirected
652 611

	
653
  ///Sets whether the the graph is undirected.
612
  ///Sets whether the graph is undirected.
654 613
  ///
655 614
  ///This setting is the default for undirected graphs.
656 615
  ///
657 616
  ///\sa directed()
658 617
   GraphToEps<T> &undirected(bool b=true) {_undirected=b;return *this;}
659 618

	
660
  ///Sets whether the the graph is directed
619
  ///Sets whether the graph is directed
661 620

	
662
  ///Sets whether the the graph is directed.
621
  ///Sets whether the graph is directed.
663 622
  ///Use it to show the edges as a pair of directed ones.
664 623
  ///
665 624
  ///This setting is the default for digraphs.
666 625
  ///
667 626
  ///\sa undirected()
668 627
  GraphToEps<T> &directed(bool b=true) {_undirected=!b;return *this;}
669 628
  
670 629
  ///Sets the title.
671 630

	
672 631
  ///Sets the title of the generated image,
673 632
  ///namely it inserts a <tt>%%Title:</tt> DSC field to the header of
674 633
  ///the EPS file.
675 634
  GraphToEps<T> &title(const std::string &t) {_title=t;return *this;}
676 635
  ///Sets the copyright statement.
677 636

	
678 637
  ///Sets the copyright statement of the generated image,
679 638
  ///namely it inserts a <tt>%%Copyright:</tt> DSC field to the header of
680 639
  ///the EPS file.
681 640
  GraphToEps<T> &copyright(const std::string &t) {_copyright=t;return *this;}
682 641

	
683 642
protected:
684 643
  bool isInsideNode(dim2::Point<double> p, double r,int t) 
685 644
  {
686 645
    switch(t) {
687 646
    case CIRCLE:
688 647
    case MALE:
689 648
    case FEMALE:
690 649
      return p.normSquare()<=r*r;
691 650
    case SQUARE:
692 651
      return p.x<=r&&p.x>=-r&&p.y<=r&&p.y>=-r;
693 652
    case DIAMOND:
694 653
      return p.x+p.y<=r && p.x-p.y<=r && -p.x+p.y<=r && -p.x-p.y<=r;
695 654
    }
696 655
    return false;
697 656
  }
698 657

	
699 658
public:
700 659
  ~GraphToEps() { }
701 660
  
702 661
  ///Draws the graph.
703 662

	
704 663
  ///Like other functions using
705 664
  ///\ref named-templ-func-param "named template parameters",
706 665
  ///this function calls the algorithm itself, i.e. in this case
707 666
  ///it draws the graph.
708 667
  void run() {
709 668
    //\todo better 'epsilon' would be nice here.
710 669
    const double EPSILON=1e-9;
711 670
    if(dontPrint) return;
712 671
    
713 672
    _graph_to_eps_bits::_NegY<typename T::CoordsMapType>
714 673
      mycoords(_coords,_negY);
715 674

	
716 675
    os << "%!PS-Adobe-2.0 EPSF-2.0\n";
717 676
    if(_title.size()>0) os << "%%Title: " << _title << '\n';
718 677
     if(_copyright.size()>0) os << "%%Copyright: " << _copyright << '\n';
719
//        << "%%Copyright: XXXX\n"
720 678
    os << "%%Creator: LEMON, graphToEps()\n";
721 679

	
722 680
    {    
723 681
#ifndef WIN32 
724 682
      timeval tv;
725 683
      gettimeofday(&tv, 0);
726 684

	
727 685
      char cbuf[26];
728 686
      ctime_r(&tv.tv_sec,cbuf);
729 687
      os << "%%CreationDate: " << cbuf;
730 688
#else
731 689
      SYSTEMTIME time;
732 690
      char buf1[11], buf2[9], buf3[5];
733 691
      
734 692
      GetSystemTime(&time);
735 693
      if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &time, 
736 694
			"ddd MMM dd", buf1, 11) &&
737 695
	  GetTimeFormat(LOCALE_USER_DEFAULT, 0, &time, 
738 696
			"HH':'mm':'ss", buf2, 9) &&
739 697
	  GetDateFormat(LOCALE_USER_DEFAULT, 0, &time, 
740 698
				"yyyy", buf3, 5)) {
741 699
	os << "%%CreationDate: " << buf1 << ' ' 
742 700
	   << buf2 << ' ' << buf3 << std::endl;
743 701
      }	  
744 702
#endif
745 703
    }
746 704

	
747 705
    if (_autoArcWidthScale) {
748 706
      double max_w=0;
749 707
      for(ArcIt e(g);e!=INVALID;++e)
750 708
	max_w=std::max(double(_arcWidths[e]),max_w);
751
      ///\todo better 'epsilon' would be nice here.
709
      //\todo better 'epsilon' would be nice here.
752 710
      if(max_w>EPSILON) {
753 711
	_arcWidthScale/=max_w;
754 712
      }
755 713
    }
756 714

	
757 715
    if (_autoNodeScale) {
758 716
      double max_s=0;
759 717
      for(NodeIt n(g);n!=INVALID;++n)
760 718
	max_s=std::max(double(_nodeSizes[n]),max_s);
761
      ///\todo better 'epsilon' would be nice here.
719
      //\todo better 'epsilon' would be nice here.
762 720
      if(max_s>EPSILON) {
763 721
	_nodeScale/=max_s;
764 722
      }
765 723
    }
766 724

	
767 725
    double diag_len = 1;
768 726
    if(!(_absoluteNodeSizes&&_absoluteArcWidths)) {
769 727
      dim2::BoundingBox<double> bb;
770 728
      for(NodeIt n(g);n!=INVALID;++n) bb.add(mycoords[n]);
771 729
      if (bb.empty()) {
772 730
	bb = dim2::BoundingBox<double>(dim2::Point<double>(0,0));
773 731
      }
774 732
      diag_len = std::sqrt((bb.bottomLeft()-bb.topRight()).normSquare());
775 733
      if(diag_len<EPSILON) diag_len = 1;
776 734
      if(!_absoluteNodeSizes) _nodeScale*=diag_len;
777 735
      if(!_absoluteArcWidths) _arcWidthScale*=diag_len;
778 736
    }
779 737
    
780 738
    dim2::BoundingBox<double> bb;
781 739
    for(NodeIt n(g);n!=INVALID;++n) {
782 740
      double ns=_nodeSizes[n]*_nodeScale;
783 741
      dim2::Point<double> p(ns,ns);
784 742
      switch(_nodeShapes[n]) {
785 743
      case CIRCLE:
786 744
      case SQUARE:
787 745
      case DIAMOND:
788 746
	bb.add(p+mycoords[n]);
789 747
	bb.add(-p+mycoords[n]);
790 748
	break;
791 749
      case MALE:
792 750
	bb.add(-p+mycoords[n]);
793 751
	bb.add(dim2::Point<double>(1.5*ns,1.5*std::sqrt(3.0)*ns)+mycoords[n]);
794 752
	break;
795 753
      case FEMALE:
796 754
	bb.add(p+mycoords[n]);
797 755
	bb.add(dim2::Point<double>(-ns,-3.01*ns)+mycoords[n]);
798 756
	break;
799 757
      }
800 758
    }
801 759
    if (bb.empty()) {
802 760
      bb = dim2::BoundingBox<double>(dim2::Point<double>(0,0));
803 761
    }
804 762
    
805 763
    if(_scaleToA4)
806 764
      os <<"%%BoundingBox: 0 0 596 842\n%%DocumentPaperSizes: a4\n";
807 765
    else {
808 766
      if(_preScale) {
809 767
	//Rescale so that BoundingBox won't be neither to big nor too small.
... ...
@@ -1069,179 +1027,161 @@
1069 1027
	}
1070 1028
	os<<'\n';
1071 1029
      }
1072 1030
      os << "grestore\n";
1073 1031
    }
1074 1032
    if(_showNodeText) {
1075 1033
      os << "%Node texts:\ngsave\n";
1076 1034
      os << "/fosi " << _nodeTextSize << " def\n";
1077 1035
      os << "(Helvetica) findfont fosi scalefont setfont\n";
1078 1036
      for(NodeIt n(g);n!=INVALID;++n) {
1079 1037
	switch(_nodeTextColorType) {
1080 1038
	case DIST_COL:
1081 1039
	  os << psOut(distantColor(_nodeColors[n])) << " setrgbcolor\n";
1082 1040
	  break;
1083 1041
	case DIST_BW:
1084 1042
	  os << psOut(distantBW(_nodeColors[n])) << " setrgbcolor\n";
1085 1043
	  break;
1086 1044
	case CUST_COL:
1087 1045
	  os << psOut(distantColor(_nodeTextColors[n])) << " setrgbcolor\n";
1088 1046
	  break;
1089 1047
	default:
1090 1048
	  os << "0 0 0 setrgbcolor\n";
1091 1049
	}
1092 1050
	os << mycoords[n].x << ' ' << mycoords[n].y
1093 1051
	   << " (" << _nodeTexts[n] << ") cshow\n";
1094 1052
      }
1095 1053
      os << "grestore\n";
1096 1054
    }
1097 1055
    if(_showNodePsText) {
1098 1056
      os << "%Node PS blocks:\ngsave\n";
1099 1057
      for(NodeIt n(g);n!=INVALID;++n)
1100 1058
	os << mycoords[n].x << ' ' << mycoords[n].y
1101 1059
	   << " moveto\n" << _nodePsTexts[n] << "\n";
1102 1060
      os << "grestore\n";
1103 1061
    }
1104 1062
    
1105 1063
    os << "grestore\nshowpage\n";
1106 1064

	
1107 1065
    //CleanUp:
1108 1066
    if(_pleaseRemoveOsStream) {delete &os;}
1109 1067
  }
1110 1068

	
1111 1069
  ///\name Aliases
1112 1070
  ///These are just some aliases to other parameter setting functions.
1113 1071

	
1114 1072
  ///@{
1115 1073

	
1116 1074
  ///An alias for arcWidths()
1117

	
1118
  ///An alias for arcWidths()
1119
  ///
1120 1075
  template<class X> GraphToEps<ArcWidthsTraits<X> > edgeWidths(const X &x)
1121 1076
  {
1122 1077
    return arcWidths(x);
1123 1078
  }
1124 1079

	
1125 1080
  ///An alias for arcColors()
1126

	
1127
  ///An alias for arcColors()
1128
  ///
1129 1081
  template<class X> GraphToEps<ArcColorsTraits<X> >
1130 1082
  edgeColors(const X &x)
1131 1083
  {
1132 1084
    return arcColors(x);
1133 1085
  }
1134 1086

	
1135 1087
  ///An alias for arcWidthScale()
1136

	
1137
  ///An alias for arcWidthScale()
1138
  ///
1139 1088
  GraphToEps<T> &edgeWidthScale(double d) {return arcWidthScale(d);}
1140 1089

	
1141 1090
  ///An alias for autoArcWidthScale()
1142

	
1143
  ///An alias for autoArcWidthScale()
1144
  ///
1145 1091
  GraphToEps<T> &autoEdgeWidthScale(bool b=true)
1146 1092
  {
1147 1093
    return autoArcWidthScale(b);
1148 1094
  }
1149 1095
  
1150 1096
  ///An alias for absoluteArcWidths()
1151

	
1152
  ///An alias for absoluteArcWidths()
1153
  ///
1154 1097
  GraphToEps<T> &absoluteEdgeWidths(bool b=true)
1155 1098
  {
1156 1099
    return absoluteArcWidths(b);
1157 1100
  }
1158 1101
  
1159 1102
  ///An alias for parArcDist()
1160

	
1161
  ///An alias for parArcDist()
1162
  ///
1163 1103
  GraphToEps<T> &parEdgeDist(double d) {return parArcDist(d);}
1164 1104
  
1165 1105
  ///An alias for hideArcs()
1166
  
1167
  ///An alias for hideArcs()
1168
  ///
1169 1106
  GraphToEps<T> &hideEdges(bool b=true) {return hideArcs(b);}
1170 1107

	
1171 1108
  ///@}
1172 1109
};
1173 1110

	
1174 1111
template<class T>
1175 1112
const int GraphToEps<T>::INTERPOL_PREC = 20;
1176 1113
template<class T>
1177 1114
const double GraphToEps<T>::A4HEIGHT = 841.8897637795276;
1178 1115
template<class T>
1179 1116
const double GraphToEps<T>::A4WIDTH  = 595.275590551181;
1180 1117
template<class T>
1181 1118
const double GraphToEps<T>::A4BORDER = 15;
1182 1119

	
1183 1120

	
1184 1121
///Generates an EPS file from a graph
1185 1122

	
1186 1123
///\ingroup eps_io
1187 1124
///Generates an EPS file from a graph.
1188
///\param g is a reference to the graph to be printed
1189
///\param os is a reference to the output stream.
1190
///By default it is <tt>std::cout</tt>
1125
///\param g Reference to the graph to be printed.
1126
///\param os Reference to the output stream.
1127
///By default it is <tt>std::cout</tt>.
1191 1128
///
1192 1129
///This function also has a lot of
1193 1130
///\ref named-templ-func-param "named parameters",
1194 1131
///they are declared as the members of class \ref GraphToEps. The following
1195 1132
///example shows how to use these parameters.
1196 1133
///\code
1197 1134
/// graphToEps(g,os).scale(10).coords(coords)
1198 1135
///              .nodeScale(2).nodeSizes(sizes)
1199 1136
///              .arcWidthScale(.4).run();
1200 1137
///\endcode
1138
///
1139
///For more detailed examples see the \ref graph_to_eps_demo.cc demo file.
1140
///
1201 1141
///\warning Don't forget to put the \ref GraphToEps::run() "run()"
1202 1142
///to the end of the parameter list.
1203 1143
///\sa GraphToEps
1204 1144
///\sa graphToEps(G &g, const char *file_name)
1205 1145
template<class G>
1206 1146
GraphToEps<DefaultGraphToEpsTraits<G> > 
1207 1147
graphToEps(G &g, std::ostream& os=std::cout)
1208 1148
{
1209 1149
  return 
1210 1150
    GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g,os));
1211 1151
}
1212 1152
 
1213 1153
///Generates an EPS file from a graph
1214 1154

	
1215 1155
///\ingroup eps_io
1216 1156
///This function does the same as
1217 1157
///\ref graphToEps(G &g,std::ostream& os)
1218 1158
///but it writes its output into the file \c file_name
1219 1159
///instead of a stream.
1220 1160
///\sa graphToEps(G &g, std::ostream& os)
1221 1161
template<class G>
1222 1162
GraphToEps<DefaultGraphToEpsTraits<G> > 
1223 1163
graphToEps(G &g,const char *file_name)
1224 1164
{
1225 1165
  return GraphToEps<DefaultGraphToEpsTraits<G> >
1226 1166
    (DefaultGraphToEpsTraits<G>(g,*new std::ofstream(file_name),true));
1227 1167
}
1228 1168

	
1229 1169
///Generates an EPS file from a graph
1230 1170

	
1231 1171
///\ingroup eps_io
1232 1172
///This function does the same as
1233 1173
///\ref graphToEps(G &g,std::ostream& os)
1234 1174
///but it writes its output into the file \c file_name
1235 1175
///instead of a stream.
1236 1176
///\sa graphToEps(G &g, std::ostream& os)
1237 1177
template<class G>
1238 1178
GraphToEps<DefaultGraphToEpsTraits<G> > 
1239 1179
graphToEps(G &g,const std::string& file_name)
1240 1180
{
1241 1181
  return GraphToEps<DefaultGraphToEpsTraits<G> >
1242 1182
    (DefaultGraphToEpsTraits<G>(g,*new std::ofstream(file_name.c_str()),true));
1243 1183
}
1244 1184

	
1245 1185
} //END OF NAMESPACE LEMON
1246 1186

	
1247 1187
#endif // LEMON_GRAPH_TO_EPS_H
0 comments (0 inline)