gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Changes in interface and internals of graph_to_eps.h
0 1 0
default
1 file changed with 17 insertions and 14 deletions:
↑ Collapse diff ↑
Ignore white space 64 line context
... ...
@@ -20,75 +20,77 @@
20 20
#define LEMON_GRAPH_TO_EPS_H
21 21

	
22 22
#include <sys/time.h>
23 23

	
24 24
#ifdef WIN32
25 25
#include <lemon/bits/mingw32_time.h>
26 26
#endif
27 27

	
28 28
#include<iostream>
29 29
#include<fstream>
30 30
#include<sstream>
31 31
#include<algorithm>
32 32
#include<vector>
33 33

	
34 34
#include<ctime>
35 35

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

	
43 43

	
44 44
///\ingroup eps_io
45 45
///\file
46 46
///\brief Simple graph drawer
47 47
///
48 48
///\author Alpar Juttner
49 49

	
50 50
namespace lemon {
51 51

	
52
template<class MT>
53
class _NegY {
54
public:
55
  typedef typename MT::Key Key;
56
  typedef typename MT::Value Value;
57
  const MT &map;
58
  int yscale;
59
  _NegY(const MT &m,bool b) : map(m), yscale(1-b*2) {}
60
  Value operator[](Key n) { return Value(map[n].x,map[n].y*yscale);}
61
};
62

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

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

	
80 82
  const Graph &g;
81 83

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

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

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

	
94 96
  double _arcWidthScale;
... ...
@@ -129,65 +131,65 @@
129 131

	
130 132
  bool _autoNodeScale;
131 133
  bool _autoArcWidthScale;
132 134

	
133 135
  bool _absoluteNodeSizes;
134 136
  bool _absoluteArcWidths;
135 137

	
136 138
  bool _negY;
137 139

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

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

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

	
175 177
///Helper class to implement the named parameters of \ref graphToEps()
176 178
///\todo Is 'helper class' a good name for this?
177 179
///
178 180
///\todo Follow PostScript's DSC.
179 181
/// Use own dictionary.
180 182
///\todo Useful new features.
181 183
/// - Linestyles: dotted, dashed etc.
182 184
/// - A second color and percent value for the lines.
183 185
template<class T> class GraphToEps : public T 
184 186
{
185 187
  // Can't believe it is required by the C++ standard
186 188
  using T::g;
187 189
  using T::os;
188 190

	
189 191
  using T::_coords;
190 192
  using T::_nodeSizes;
191 193
  using T::_nodeShapes;
192 194
  using T::_nodeColors;
193 195
  using T::_arcColors;
... ...
@@ -639,111 +641,112 @@
639 641
  ///Sets the color of the node texts to be as different from the node color
640 642
  ///as it is possible
641 643
  ///
642 644
  GraphToEps<T> &distantColorNodeTexts()
643 645
  {_nodeTextColorType=DIST_COL;return *this;}
644 646
  ///Sets the color of the node texts to be black or white and always visible.
645 647

	
646 648
  ///Sets the color of the node texts to be black or white according to
647 649
  ///which is more 
648 650
  ///different from the node color
649 651
  ///
650 652
  GraphToEps<T> &distantBWNodeTexts()
651 653
  {_nodeTextColorType=DIST_BW;return *this;}
652 654

	
653 655
  ///Gives a preamble block for node Postscript block.
654 656
  
655 657
  ///Gives a preamble block for node Postscript block.
656 658
  ///
657 659
  ///\sa nodePsTexts()
658 660
  GraphToEps<T> & nodePsTextsPreamble(const char *str) {
659 661
    _nodePsTextsPreamble=str ;return *this;
660 662
  }
661 663
  ///Sets whether the the graph is undirected
662 664

	
663 665
  ///Sets whether the the graph is undirected
664 666
  ///
665 667
  GraphToEps<T> &undirected(bool b=true) {_undirected=b;return *this;}
666 668

	
667 669
  ///Sets whether the the graph is directed
668 670

	
669 671
  ///Sets whether the the graph is directed.
670 672
  ///Use it to show the edges as a pair of directed ones.
671
  GraphToEps<T> &bidir(bool b=true) {_undirected=!b;return *this;}
673
  GraphToEps<T> &directed(bool b=true) {_undirected=!b;return *this;}
672 674

	
673 675
  ///Sets the title.
674 676

	
675 677
  ///Sets the title of the generated image,
676 678
  ///namely it inserts a <tt>%%Title:</tt> DSC field to the header of
677 679
  ///the EPS file.
678 680
  GraphToEps<T> &title(const std::string &t) {_title=t;return *this;}
679 681
  ///Sets the copyright statement.
680 682

	
681 683
  ///Sets the copyright statement of the generated image,
682 684
  ///namely it inserts a <tt>%%Copyright:</tt> DSC field to the header of
683 685
  ///the EPS file.
684 686
  ///\todo Multiline copyright notice could be supported.
685 687
  GraphToEps<T> &copyright(const std::string &t) {_copyright=t;return *this;}
686 688

	
687 689
protected:
688 690
  bool isInsideNode(dim2::Point<double> p, double r,int t) 
689 691
  {
690 692
    switch(t) {
691 693
    case CIRCLE:
692 694
    case MALE:
693 695
    case FEMALE:
694 696
      return p.normSquare()<=r*r;
695 697
    case SQUARE:
696 698
      return p.x<=r&&p.x>=-r&&p.y<=r&&p.y>=-r;
697 699
    case DIAMOND:
698 700
      return p.x+p.y<=r && p.x-p.y<=r && -p.x+p.y<=r && -p.x-p.y<=r;
699 701
    }
700 702
    return false;
701 703
  }
702 704

	
703 705
public:
704 706
  ~GraphToEps() { }
705 707
  
706 708
  ///Draws the graph.
707 709

	
708 710
  ///Like other functions using
709 711
  ///\ref named-templ-func-param "named template parameters",
710 712
  ///this function calles the algorithm itself, i.e. in this case
711 713
  ///it draws the graph.
712 714
  void run() {
713 715
    ///\todo better 'epsilon' would be nice here.
714 716
    const double EPSILON=1e-9;
715 717
    if(dontPrint) return;
716 718
    
717
    _NegY<typename T::CoordsMapType> mycoords(_coords,_negY);
719
    _graph_to_eps_bits::_NegY<typename T::CoordsMapType>
720
      mycoords(_coords,_negY);
718 721

	
719 722
    os << "%!PS-Adobe-2.0 EPSF-2.0\n";
720 723
    if(_title.size()>0) os << "%%Title: " << _title << '\n';
721 724
     if(_copyright.size()>0) os << "%%Copyright: " << _copyright << '\n';
722 725
//        << "%%Copyright: XXXX\n"
723 726
    os << "%%Creator: LEMON, graphToEps()\n";
724 727
    
725 728
    {
726 729
      char cbuf[50];
727 730
      timeval tv;
728 731
      gettimeofday(&tv, 0);
729 732
      ctime_r(&tv.tv_sec,cbuf);
730 733
      os << "%%CreationDate: " << cbuf;
731 734
    }
732 735

	
733 736
    if (_autoArcWidthScale) {
734 737
      double max_w=0;
735 738
      for(ArcIt e(g);e!=INVALID;++e)
736 739
	max_w=std::max(double(_arcWidths[e]),max_w);
737 740
      ///\todo better 'epsilon' would be nice here.
738 741
      if(max_w>EPSILON) {
739 742
	_arcWidthScale/=max_w;
740 743
      }
741 744
    }
742 745

	
743 746
    if (_autoNodeScale) {
744 747
      double max_s=0;
745 748
      for(NodeIt n(g);n!=INVALID;++n)
746 749
	max_s=std::max(double(_nodeSizes[n]),max_s);
747 750
      ///\todo better 'epsilon' would be nice here.
748 751
      if(max_s>EPSILON) {
749 752
	_nodeScale/=max_s;
0 comments (0 inline)