// Copyright (c) 2001 Utrecht University (The Netherlands), // ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany), // INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg // (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria), // and Tel-Aviv University (Israel). All rights reserved. // // This file is part of CGAL (www.cgal.org); you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; version 2.1 of the License. // See the file LICENSE.LGPL distributed with CGAL. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // // // Author(s) : #ifndef CGAL_IO_PS_STREAM_H #define CGAL_IO_PS_STREAM_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include CGAL_BEGIN_NAMESPACE class PS_Stream; template class PS_Manipulator { friend PS_Stream& operator<< <> (PS_Stream& , const PS_Manipulator &); public: PS_Manipulator(PS_Stream& (PS_Stream::*f)(T),T v): _PS_func(f), param(v) {} protected: PS_Stream& (PS_Stream::*_PS_func)(T); T param; }; template PS_Stream& operator << (PS_Stream& pss, const PS_Manipulator &m) { (pss.*m._PS_func)(m.param); return pss; } template class PS_Manipulator_creator { public: PS_Manipulator_creator(PS_Stream& (PS_Stream::*f)(T)): _PS_func(f) {} PS_Manipulator operator() (T param) { return PS_Manipulator(_PS_func,param); } protected: PS_Stream& (PS_Stream::*_PS_func)(T); }; typedef const char *DashStyle; class PS_Stream { public: typedef Bbox_2 PS_BBox; static const DashStyle SOLID; static const DashStyle DASH1; static const DashStyle DASH2; static const DashStyle DASH3; static const DashStyle DASH4; static const DashStyle DASH5; static const DashStyle DASH6; static const float CM; static const float INCH; static const float POINT; enum OutputMode {READABLE, QUIET, READABLE_EPS, QUIET_EPS, GS_VIEW}; enum DotStyle {NONE, XCROSS, ICROSS, EDOT, FDOT, EBOX, FBOX}; class Axis { friend class PS_Stream; friend PS_Stream & operator << (PS_Stream& ps, const Axis& g); public: Axis(double x, double y, unsigned int t=0) : _stepx(x), _stepy(y), _thick(t) {} Axis(double xy, unsigned int t=0) : _stepx(xy),_stepy(xy), _thick(t) {} Axis(): _stepx(1.0), _stepy(1.0), _thick(0) {} double stepx() const { return _stepx;} double stepy() const { return _stepy;} unsigned int thickness() const { return _thick;} protected: double _stepx; double _stepy; unsigned int _thick; }; class Grid { friend class PS_Stream; friend PS_Stream & operator << (PS_Stream& ps, const Grid& g); public: Grid(double x, double y, DashStyle str="[1 5] 0") : _stepx(x), _stepy(y) {_style=strdup(str);} Grid(double xy, DashStyle str="[1 5] 0") : _stepx(xy), _stepy(xy) {_style=strdup(str);} Grid() : _stepx(1.0), _stepy(1.0), _style("[1 5] 0") {} double stepx() const { return _stepx;} double stepy() const { return _stepy;} DashStyle style() const { return _style;} protected: double _stepx; double _stepy; DashStyle _style; }; class Label { friend class PS_Stream; friend PS_Stream & operator << (PS_Stream& ps, const Label& txt); public: Label(const char* txt) { _text=strdup(txt);} Label() { _text="";} const char* text() const { return _text;} protected: const char* _text; }; class Latex_Label { friend class PS_Stream; friend PS_Stream& operator << (PS_Stream& ps, Latex_Label& txt); public: // Only text can be define by user Latex_Label(const char* txt) { _text=strdup(txt);posx=0;posy=0;} Latex_Label() { _text="";posx=0;posy=0;} float xpos() const {return posx;} float ypos() const {return posy;} const char* text() const { return _text;} protected: // These functions are private because the position of the string // must never appears to the user // Only stream modifiers will access these data void setposition(float x, float y) { posx=x;posy=y;} Latex_Label(const char* txt,float x, float y) {_text=strdup(txt);posx=x;posy=y;} // Slots const char* _text; float posx; float posy; }; typedef std::list List_Label; class Border { friend class PS_Stream; friend PS_Stream& operator << (PS_Stream &ps, const Border &b); public: Border(int s=0) { _size=s;} int size() const { return _size;} protected: int _size; }; class Context { friend class PS_Stream; public: Context() : _border_color(Color(0,0,0)), _fill_color(Color(0,0,0)),_dot_style(XCROSS),_dot_size(5), _thickness(0),_line_style(SOLID),_fill(false), _font("Helvetica"),_font_size(12), _anchor_point(Point_2 > (0,0)) {} Context(const Context& c) : _border_color(c.get_border_color()),_fill_color(c.get_fill_color()), _dot_style(c.get_dot_style()), _dot_size(c.get_dot_size()), _thickness(c.get_thickness()), _line_style(strdup(c.get_line_style())), _fill(c.get_fill()), _font(strdup(c.get_font())), _font_size(c.get_font_size()), _anchor_point(c.get_pos()) {}; // Accessor Color get_border_color() const {return _border_color;} Color get_fill_color() const {return _fill_color;} DotStyle get_dot_style() const {return _dot_style;} unsigned int get_dot_size() const {return _dot_size;} unsigned int get_thickness() const {return _thickness;} unsigned int get_font_size() const {return _font_size;} DashStyle get_line_style() const {return _line_style;} const char* get_font() const {return _font;} bool get_fill() const {return _fill;} Point_2 > get_pos() const {return _anchor_point;} void set_border_color(const Color& c) {_border_color=c;} void set_fill_color(const Color& c) {_fill_color=c;} void set_dot_style(DotStyle& s) {_dot_style=s;} void set_dot_size(unsigned int s) {_dot_size=s;} void set_thickness(unsigned int t) {_thickness=t;} void set_font_size(unsigned int s) {_font_size=s;} void set_fill(bool& b) {_fill=b;} void set_current_pos(const Point_2 >& p) {_anchor_point=p;} void set_line_style(DashStyle style) {_line_style=strdup(style);} void set_font(const char *font) {_font=strdup(font);} protected: // Store the current border color Color _border_color; // Store the current fill color Color _fill_color; // Store the current dot style enum DotStyle _dot_style; // Store the current dot size unsigned int _dot_size; // Store the current line thickness unsigned int _thickness; // Store the current line style DashStyle _line_style; // Define if a polygone must be fill or not bool _fill; // Define if direction must be shown. bool _dir; // Store the name of the font to use. It is only used for standart Label, // not for Latex Label. const char* _font; // Store the size of the font. It is only used for standart Label, // not for Latex Label. unsigned int _font_size; //Anchor point: Point_2 > _anchor_point; }; //Constructors used for PS_Stream 3D PS_Stream(std::ostream& os,OutputMode = QUIET); PS_Stream(const char* fname, OutputMode = QUIET); PS_Stream(float H,std::ostream& os,OutputMode = QUIET); PS_Stream(float H, const char* fname, OutputMode = QUIET); //Constructors PS_Stream(const PS_BBox& bb, std::ostream& os, OutputMode = QUIET); PS_Stream(const PS_BBox& bb, const char* fname, OutputMode = QUIET); PS_Stream(const PS_BBox& bb,float H, std::ostream& os, OutputMode = QUIET); PS_Stream(const PS_BBox& bb,float H, const char* fname, OutputMode = QUIET); PS_Stream(const PS_BBox& bb,float L, float H, std::ostream& os, OutputMode = QUIET); PS_Stream(const PS_BBox& bb,float L, float H, const char* fname, OutputMode = QUIET); PS_Stream(const PS_BBox& bb,float L, float H); ~PS_Stream(); PS_Stream& set_border_color(const Color&); PS_Stream& set_fill_color(const Color&); PS_Stream& set_point_size(unsigned int); PS_Stream& set_line_width(unsigned int); PS_Stream& set_point_style(enum DotStyle); PS_Stream& set_line_style(DashStyle); PS_Stream& set_fill(bool); PS_Stream& set_default_context(void); PS_Stream& set_current_context(const Context&); PS_Stream& set_point(Point_2< Cartesian >); PS_Stream& set_axis(Axis&); PS_Stream& set_grid(Grid&); PS_Stream& put_ps_label(const char*); PS_Stream& put_latex_label(const char*); PS_Stream& put_border(unsigned int); PS_Stream& set_font(const char*); PS_Stream& set_font_size(unsigned int); //Accessors std::ostream& os() {return _os;} List_Label& list() {return _ll;} const Context context() const {return ctxt;} bool gs_output() const {return (bool)(mode()==GS_VIEW);} PS_BBox bbox() const {return _bbox;} int width() const {return _width;} int height() const {return _height;} OutputMode mode() const {return _mode;} void set_scale(const PS_BBox& bb) { _xratio=_width/(bb.xmax()-bb.xmin()); _yratio=_height/(bb.ymax()-bb.ymin()); } void set_window(PS_BBox bb,float H) { _width=(int)((bb.xmax()-bb.xmin())*H/(bb.ymax()-bb.ymin())); } // Utils double xratio() { return _xratio;} double yratio() { return _yratio;} double x2ps(double x) { return (x-_bbox.xmin())*xratio();} double y2ps(double y) { return (y-_bbox.ymin())*yratio();} bool is_eps(); bool is_readable(); protected: // PS_Stream(const PS_BBox& bb); // PS_Stream(const PS_BBox& bb,float H); // PS_Stream(const PS_BBox& bb,float L, float H); // Manipulation du contexte. void setdefault(); void setcontext(); // Pour inserer l'entete void insert_catalogue(); // Define the scale. double _xratio; double _yratio; // Define the boounding box PS_BBox _bbox; // OutputMode OutputMode _mode; // Size of output. int _width; int _height; // Graphical Context Context ctxt; // In case it's a file, we need to store the object to be able to reference // it, hence the of. std::ofstream of; std::ostream& _os; //List of Latex Labels. They will be inserted at the end of the file. List_Label _ll; }; extern const PS_Stream::Context CTXT_DEFAULT; PS_Stream & operator <<(PS_Stream& , const PS_Stream::Border& ); PS_Stream & operator <<(PS_Stream& , const PS_Stream::Axis& ); PS_Stream & operator <<(PS_Stream& , const PS_Stream::Grid& ); PS_Stream & operator <<(PS_Stream& , const PS_Stream::Label&); PS_Stream& operator << (PS_Stream& , const PS_Stream::Latex_Label& txt); extern PS_Manipulator_creator fill_color; extern PS_Manipulator_creator border_color; extern PS_Manipulator_creator point_size; extern PS_Manipulator_creator point_style; extern PS_Manipulator_creator line_style; extern PS_Manipulator_creator line_width; extern PS_Manipulator_creator fill; extern PS_Manipulator_creator current_context; extern PS_Manipulator_creator > > move_to; extern PS_Manipulator_creator show_axis; extern PS_Manipulator_creator show_grid; extern PS_Manipulator_creator ps_label; extern PS_Manipulator_creator latex_label; extern PS_Manipulator_creator border; extern PS_Manipulator_creator font; extern PS_Manipulator_creator font_size; #ifdef CGAL_POINT_2_H template < class R > PS_Stream & operator <<(PS_Stream& ps, const Point_2& p) { if (ps.is_readable()) { ps.os() << "%CGAL% Point" << std::endl; ps.os() << "%CGAL% "< PS_Stream & operator <<(PS_Stream& ps, const Segment_2& s) { if (ps.is_readable()) { ps.os() << "%CGAL% Segment" << std::endl; ps.os() << "%CGAL% "< PS_Stream & operator <<(PS_Stream& ps, const Line_2& l) { if (ps.is_readable()) { ps.os() << "%CGAL% Line" << std::endl; ps.os() << "%CGAL% "< PS_Stream & operator <<(PS_Stream& ps, const Ray_2& r) { typedef Direction_2 > dir; Line_2 l=r.supporting_line(); dir haut(0,1); dir bas(0,-1); if (ps.is_readable()) { ps.os() << "%CGAL% Ray" << std::endl; ps.os() << "%CGAL% "<bas || r.direction() PS_Stream & operator <<(PS_Stream& ps,const Parabola& p) { if (ps.is_readable()) { ps.os() << "%CGAL% Parabola" << std::endl; ps.os() << "%CGAL% Base "< PS_Stream & operator <<(PS_Stream& ps,const Triangle_2& t) { if (ps.is_readable()) { ps.os() << "%CGAL% Triangle" << std::endl; for (int i=0;i<3;i++) ps.os() << "%CGAL " << t[i].x() << " " << t[i].y() << std::endl; } for (int i=0;i<4;i++) ps.os() << ps.x2ps(t[i].x())<< " " << ps.y2ps(t[i].y()) << " "; ps.os() << "tr "; if (ps.context().get_fill()) { ps.os() << "gsave " << std::endl; ps.os() << ps.context().get_fill_color().r() << " " << ps.context().get_fill_color().g() << " " << ps.context().get_fill_color().b() << " setcolor fill grestore " < PS_Stream & operator <<(PS_Stream& ps,const Iso_rectangle_2& r) { if (ps.is_readable()) { ps.os() << "%CGAL% Rectangle" << std::endl; for (int i=0;i<4;i++) ps.os() << "%CGAL " << r[i].x() << " " << r[i].y() << std::endl; } for (int i=0;i<5;i++) ps.os() << ps.x2ps(r[i].x()) << " " << ps.y2ps(r[i].y()) << " "; ps.os() << "re "; if (ps.context().get_fill()) { ps.os() << "gsave " << std::endl; ps.os() << ps.context().get_fill_color().r() << " " << ps.context().get_fill_color().g() << " " << ps.context().get_fill_color().b() << " setcolor fill grestore " < PS_Stream & operator <<(PS_Stream& ps, const Circle_2& c) { if (ps.is_readable()) { ps.os() << "%CGAL% Circle" << std::endl; ps.os() << "%CGAL " << c.center().x()<<" "<