\documentclass[]{article} \usepackage{amssymb} \usepackage{fw-latex} \usepackage{cgal} \usepackage{epsf} \textwidth=6in \textheight=8.9in \oddsidemargin=0.25in \evensidemargin=0.25in \topmargin=-0.5in \begin{document} @p typesetter = tex @p no_doc_header @p maximum_output_line_length = 120 @p maximum_input_line_length = 120 \title{\bf The CGAL PostScript Stream} \author{Franck Descollonges \\ INRIA Sophia Antipolis} \date{29/01/1997} \maketitle \section{Introduction} {\it Postscript} is a page description language. It is a programming language designed to convey a description of virtually any desired page to a printer. We provide a Postscript output for all geometric classes of \cgal. Thanks to this stream, you will be able to create file printable or a file you will be able to insert in Latex documents. Indeed the generate output file can be an EPSF file. \section{The Postscript Stream Class} This class is the Postscript Stream class. It is the one containing all methods used to create, modify a Postscript output. The following two macros contain the public and the private part respectively. @$@+=@{@- typedef const char *DashStyle; class CGAL_PS_Stream { public: typedef CGAL_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}; @} \subsection{The Graphical Environment : Auxiliary classes} Before speacking about the Postscript stream, we have to introduce some auxiliary classes. \subsubsection{The Axis Class } If you want to represente axis on the postscript output, you have to create an axis object. You can set the step between two marks on the x-axis and the y-axis. If the padx or the pady is 0 no mark are displayed on the axis. The thick member contains thickness of the lines rrepresenting the axis. You can insert only one axis object in a postscript stream. @$@+=@{@- class Axis { friend CGAL_PS_Stream; friend CGAL_PS_Stream &operator<<(CGAL_PS_Stream &ps, const Axis &g); public: Axis(double x, double y, unsigned int t=0.0) : _stepx(x), _stepy(y), _thick(t) {} Axis(double xy, unsigned int t=0.0) : _stepx(xy),_stepy(xy), _thick(t) {} Axis(): _stepx(1.0), _stepy(1.0), _thick(0.0) {} double stepx() const { return _stepx;} double stepy() const { return _stepy;} double thickness() const { return _thick;} private: double _stepx; double _stepy; bool _thick; }; @} \subsubsection{The Grid Class } You can insert grids in a postscript stream. You have to create an object and select the step beetween two line for the x-axis and the y-axis... You can select the style of the mark and insert many grid of differents styles. @$@+=@{@- class Grid { friend CGAL_PS_Stream; friend CGAL_PS_Stream &operator<<(CGAL_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") {} private: double stepx() const { return _stepx;} double stepy() const { return _stepy;} DashStyle style() const { return _style;} double _stepx; double _stepy; DashStyle _style; }; @} \subsubsection{The Label class} The Label class is used to insert text in a postscript output. You have just to define a Label object and insert it in the stream to display the string in the postscript output. Default font and size is used to display texts but you are able to change this using the modifiers of the stream. @$@+=@{@- class Label { friend CGAL_PS_Stream; friend CGAL_PS_Stream &operator<<(CGAL_PS_Stream &ps, const Label &txt); public: Label(const char* txt) { _text=strdup(txt);} private: Label() { _text="";} const char* text() const { return _text;} const char* _text; }; @} \subsubsection{The Latex label class} These class is used to insert text which will be only display with Latex. These labels used default latex font to be displayed. You can can change font and style (for exemple math style) by using standart latex commands as string like : \begin{verbatim} {$\alpha^{y}_{i}$} \end{verbatim} These labels wont be displayed on a gs view but only with latex. To include such a file you have to type ("toto.ps" is the file in which the Postscript output of CGAL had been redirected) : \begin{verbatim} \documentclass[]{article} \begin{document} \def\Ipe#1{\def\IPEfile{#1}\input{#1}} before. \begin{figure*}[h] \begin{center} \Ipe{toto.ps} \end{center} \end{figure*} after. \end{document} \end{verbatim} @$@+=@{@- class Latex_Label { friend CGAL_PS_Stream; friend CGAL_PS_Stream &operator<<(CGAL_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;} private: // 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;} float xpos() const {return posx;}; float ypos() const {return posy;}; const char* text() const { return _text;}; // Slots const char* _text; float posx; float posy; }; @} I need to insert all Latex labels at the same position (at the end of the file.) So i need to save all data in a list. It is why i define a Lsit of latex label. @$@+=@{@- typedef list List_Label; @} \subsubsection{The Border class} The border class is used to insert a border in a stream. Users just need to define a border, and to insert it in the stream. The postscript output will display this border. @$@+=@{@- class Border { friend CGAL_PS_Stream; friend CGAL_PS_Stream &operator<<(CGAL_PS_Stream &ps, const Border &b); public: Border(int s=0) { _size=s;} private: int size() const { return _size;} int _size; }; @} \subsubsection{The Context class} The Context class define a graphical context. It is used to select the style of the drawing. You can create a context (set to DEFAULT value) and copy the current context. You only can change the current context of the postscript stream by inserting modifiers in the stream. The context can be globaly set with a modifier in the Postscript stream thanks to this class. \begin{figure}[h] \centerline{\epsffile{demo.ps}} \end{figure} The following two macros contain the public and the private part respectively. \subsubsection*{The Public Interface of the Context class} @$@+=@{@- class Context { friend CGAL_PS_Stream; public: Context() : _border_color(CGAL_Color(0,0,0)), _fill_color(CGAL_Color(0,0,0)),_dot_style(XCROSS),_dot_size(5), _thickness(0),_line_style(SOLID),_fill(false), _font("Helvetica"),_font_size(12), _anchor_point(CGAL_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 CGAL_Color get_border_color() const {return _border_color;} CGAL_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;} CGAL_Point_2 > get_pos() const {return _anchor_point;} void set_border_color(CGAL_Color& c) {_border_color=c;} void set_fill_color(CGAL_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 CGAL_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);}@} \subsubsection*{The Private part of the Context class} @$@+=@{@- private: // Store the current border color CGAL_Color _border_color; // Store the current fill color CGAL_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: CGAL_Point_2 > _anchor_point; }; @} \subsection{Specification of the CGAL\_PS\_Stream class} \subsubsection{The public part of CGAL\_PS\_Stream} The different constructors of the Postscipt Stream allow a very easy definition of the working area. For all constructors, you need to define a bounding box. This is the maximum area of real objects represented in the postscript view. In this coonstructors, the whole page is used, the bounding box is defined by bb. @$@+=@{@- CGAL_PS_Stream(const PS_BBox &bb, ostream &os, OutputMode = QUIET); @} The same as above but the output stream will be a file which name is fname. @$@+=@{@- CGAL_PS_Stream(const PS_BBox &bb, const char *fname, OutputMode = QUIET); @} These constructors specify the size of the postscript result. (size is given in postscript dots.) You can select the desired height of the output. The width of the output will be calculated to keep circle round. In an output stream : @$@+=@{@- CGAL_PS_Stream(const PS_BBox &bb,float H, ostream &os, OutputMode = QUIET); @} In a file named fname : @$@+=@{@- CGAL_PS_Stream(const PS_BBox &bb,float H, const char *fname, OutputMode = QUIET); @} These constructors specify the size of the postscript result in postscipt dots. In an output stream : @$@+=@{@- CGAL_PS_Stream(const PS_BBox &bb,float L, float H, ostream &os, OutputMode = QUIET); @} In a file named fname : @$@+=@{@- CGAL_PS_Stream(const PS_BBox &bb,float L, float H, const char *fname, OutputMode = QUIET); @} Destructor : @$@+=@{@- ~CGAL_PS_Stream(); @} //Manipulators @$@+=@{@- CGAL_PS_Stream& _SetBorderColor(CGAL_Color &); CGAL_PS_Stream& _SetFillColor(CGAL_Color &); CGAL_PS_Stream& _SetPointSize(unsigned int); CGAL_PS_Stream& _SetLineWidth(unsigned int); CGAL_PS_Stream& _SetPointStyle(enum DotStyle); CGAL_PS_Stream& _SetLineStyle(DashStyle); CGAL_PS_Stream& _SetFill(bool); CGAL_PS_Stream& _SetDefaultContext(void); CGAL_PS_Stream& _SetCurrentContext(const Context &); CGAL_PS_Stream& _ShowDirection(bool); CGAL_PS_Stream& _MoveTo(CGAL_Point_2< CGAL_Cartesian >); CGAL_PS_Stream& _ShowAxis(Axis &); CGAL_PS_Stream& _ShowGrid(Grid &); CGAL_PS_Stream& _PutPsLabel(const char *); CGAL_PS_Stream& _PutLatexLabel(const char *); CGAL_PS_Stream& _PutBorder(unsigned int); CGAL_PS_Stream& _SetFont(const char *); CGAL_PS_Stream& _SetFontSize(unsigned int); //Accessors 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;} // 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(); @} \subsubsection{The Private Part of CGAL\_PS\_Stream} @$@+=@{@- private: @} Constructors in a pipe : @$@+=@{@- CGAL_PS_Stream(const PS_BBox &bb); CGAL_PS_Stream(const PS_BBox &bb,float H); CGAL_PS_Stream(const PS_BBox &bb,float L, float H); @} Default Constructor protected. @$@+=@{@- CGAL_PS_Stream(); // 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,_height; // Graphical Context Context ctxt; // The Output stream #ifdef CGAL_WORKAROUND_016 _IO_ostream_withassign &_os; #else ostream_withassign &_os; #endif //List of Latex Labels. They will be inserted at the end of the file. List_Label _ll; }; @} Definition of external fonctions and variables @$@+=@{@- extern const CGAL_PS_Stream::Context CGAL_CTXT_DEFAULT; CGAL_PS_Stream &operator<<(CGAL_PS_Stream &ps, const CGAL_PS_Stream::Border &b); CGAL_PS_Stream &operator<<(CGAL_PS_Stream &ps, const CGAL_PS_Stream::Axis &g); CGAL_PS_Stream &operator<<(CGAL_PS_Stream &ps, const CGAL_PS_Stream::Grid &g); CGAL_PS_Stream &operator<<(CGAL_PS_Stream &ps, const CGAL_PS_Stream::Label &txt); CGAL_PS_Stream &operator<<(CGAL_PS_Stream &ps, const CGAL_PS_Stream::Latex_Label &txt); extern CGAL_PS_Modifier_creator set_fill_color; extern CGAL_PS_Modifier_creator set_border_color; extern CGAL_PS_Modifier_creator set_point_size; extern CGAL_PS_Modifier_creator set_point_style; extern CGAL_PS_Modifier_creator set_line_style; extern CGAL_PS_Modifier_creator set_line_width; extern CGAL_PS_Modifier_creator set_fill; extern CGAL_PS_Modifier_creator set_current_context; extern CGAL_PS_Modifier_creator show_direction; extern CGAL_PS_Modifier_creator > > move_to; //extern CGAL_PS_Modifier_creator show_axis; //extern CGAL_PS_Modifier_creator show_grid; //extern CGAL_PS_Modifier_creator put_ps_label; //extern CGAL_PS_Modifier_creator put_latex_label; //extern CGAL_PS_Modifier_creator put_border; extern CGAL_PS_Modifier_creator set_font; extern CGAL_PS_Modifier_creator set_font_size; @} \subsection{Implementation : Constructors and Destructors} Definition of constants : @$@+=@{@- const float CGAL_PS_Stream::CM=28.4; const float CGAL_PS_Stream::INCH=72.0; const float CGAL_PS_Stream::POINT=1.0; const DashStyle CGAL_PS_Stream::SOLID="[] 0 "; const DashStyle CGAL_PS_Stream::DASH2="[5 5] 0 "; const DashStyle CGAL_PS_Stream::DASH3="[10 10] 0 "; const DashStyle CGAL_PS_Stream::DASH6="[10 6 4 6] 0 "; const DashStyle CGAL_PS_Stream::DASH4="[10 5] 0 "; const DashStyle CGAL_PS_Stream::DASH5="[5 10] 0 "; const DashStyle CGAL_PS_Stream::DASH1="[2 2] 0 "; extern const CGAL_PS_Stream::Context CGAL_CTXT_DEFAULT=CGAL_PS_Stream::Context(); @} Constructors : @$@+=@{@- /* CGAL_PS_Stream::CGAL_PS_Stream(const PS_BBox &bb) : _bbox(bb), _os(cerr), _mode(GS_VIEW) { FILE *fp = popen("gs -","w"); if(!fp){ cerr << "Could not open pipe to gs" << endl ; exit(-1); } os().attach(fileno(fp)); insert_catalogue(); } CGAL_PS_Stream::CGAL_PS_Stream(const PS_BBox &bb,float L, float H) : _bbox(bb), _os(cerr), _mode(GS_VIEW), _width(L), _height(H) { insert_catalogue(); _xratio=_width/(_bbox.xmax()-_bbox.xmin()); _yratio=_height/(_bbox.ymax()-_bbox.ymin()); }; */ @} Alternatively you can pass an output stream as argument. The formatted Postscript output goes to this stream then, which typically will be {\tt cout} or a file (passing a {\tt fstream}). @$@+=@{@- CGAL_PS_Stream::CGAL_PS_Stream(const PS_BBox &bb, ostream &os, OutputMode mode) :_bbox(bb), _mode(mode), _width((int)21*CM), _height((int)29.7*CM), _os(cerr) { _xratio=_width/(_bbox.xmax()-_bbox.xmin()); _yratio=_height/(_bbox.ymax()-_bbox.ymin()); _os=os; insert_catalogue(); } CGAL_PS_Stream::CGAL_PS_Stream(const PS_BBox &bb, const char *fname, OutputMode mode) : _bbox(bb),_mode(mode),_width((int)21*CM), _height((int)29.7*CM),_os(cerr) { _xratio=_width/(_bbox.xmax()-_bbox.xmin()); _yratio=_height/(_bbox.ymax()-_bbox.ymin()); static ofstream os(fname); _os=os; insert_catalogue(); } CGAL_PS_Stream::CGAL_PS_Stream(const PS_BBox &bb,float H, ostream &os, OutputMode mode) : _bbox(bb), _mode(mode), _height(H), _os(cerr) { _width=(bb.xmax()-bb.xmin())*H/(bb.ymax()-bb.ymin()); _xratio=_width/(_bbox.xmax()-_bbox.xmin()); _yratio=_height/(_bbox.ymax()-_bbox.ymin()); _os=os; insert_catalogue(); } CGAL_PS_Stream::CGAL_PS_Stream(const PS_BBox &bb,float H, const char *fname, OutputMode m) : _bbox(bb), _mode(m), _height(H), _os(cerr) { static ofstream os(fname); _os=os; _width=(bb.xmax()-bb.xmin())*H/(bb.ymax()-bb.ymin()); _xratio=_width/(_bbox.xmax()-_bbox.xmin()); _yratio=_height/(_bbox.ymax()-_bbox.ymin()); insert_catalogue(); } CGAL_PS_Stream::CGAL_PS_Stream(const PS_BBox &bb,float L, float H, ostream &os, OutputMode mode) : _bbox(bb), _mode(mode), _width(L), _height(H), _os(cerr) { _os=os; _xratio=_width/(_bbox.xmax()-_bbox.xmin()); _yratio=_height/(_bbox.ymax()-_bbox.ymin()); insert_catalogue(); } CGAL_PS_Stream::CGAL_PS_Stream(const PS_BBox &bb,float L, float H, const char *fname, OutputMode mode) : _bbox(bb), _mode(mode),_width(L),_height(H), _os(cerr) { static ofstream os(fname); _os=os; _xratio=_width/(_bbox.xmax()-_bbox.xmin()); _yratio=_height/(_bbox.ymax()-_bbox.ymin()); insert_catalogue(); } @} Destructor : The destructor insert all the latex instruction if needed. Then, it inserts all the latex labels, and finaly it closes the stream. @$@+=@{@- CGAL_PS_Stream::~CGAL_PS_Stream() { List_Label tmp=list(); if (!list().empty()) { os() << "%%}\\makeatletter\\let\\@@notdefinable\\relax" <+=@{@- #ifndef CGAL_PS_MANIP_DEF #define CGAL_PS_MANIP_DEF CGAL_PS_Modifier_creator set_border_color(&CGAL_PS_Stream::_SetBorderColor); CGAL_PS_Modifier_creator set_fill_color(&CGAL_PS_Stream::_SetFillColor); CGAL_PS_Modifier_creator set_point_size(&CGAL_PS_Stream::_SetPointSize); CGAL_PS_Modifier_creator set_point_style(&CGAL_PS_Stream::_SetPointStyle); CGAL_PS_Modifier_creator set_line_style(&CGAL_PS_Stream::_SetLineStyle); CGAL_PS_Modifier_creator set_line_width(&CGAL_PS_Stream::_SetLineWidth); CGAL_PS_Modifier_creator set_fill(&CGAL_PS_Stream::_SetFill); CGAL_PS_Modifier_creator set_current_context(&CGAL_PS_Stream::_SetCurrentContext); CGAL_PS_Modifier_creator show_direction(&CGAL_PS_Stream::_ShowDirection); CGAL_PS_Modifier_creator > > move_to(&CGAL_PS_Stream::_MoveTo); CGAL_PS_Modifier_creator show_axis(&CGAL_PS_Stream::_ShowAxis); CGAL_PS_Modifier_creator show_grid(&CGAL_PS_Stream::_ShowGrid); CGAL_PS_Modifier_creator put_ps_label(&CGAL_PS_Stream::_PutPsLabel); CGAL_PS_Modifier_creator put_latex_label(&CGAL_PS_Stream::_PutLatexLabel); CGAL_PS_Modifier_creator put_border(&CGAL_PS_Stream::_PutBorder); CGAL_PS_Modifier_creator set_font(&CGAL_PS_Stream::_SetFont); CGAL_PS_Modifier_creator set_font_size(&CGAL_PS_Stream::_SetFontSize); #endif //CGAL_PS_MANIP_DEF @} This is the class that allows to use manipulators in streams. It is define with a pointer on a function with only one parameter and returning the same type of value. This class contains a field named param that is the value of the modifier inserted in the stream. We will see further the definitions off the functions called by this way. @$@+=@{@- #ifndef CGAL_PS_MANIP_H_ #define CGAL_PS_MANIP_H_ class CGAL_PS_Stream; template class CGAL_PS_Modifier { friend CGAL_PS_Stream& operator<<(CGAL_PS_Stream& pss, const CGAL_PS_Modifier &); public: CGAL_PS_Modifier(CGAL_PS_Stream& (CGAL_PS_Stream::*f)(T),T v): _PS_func(f), param(v) {} private: CGAL_PS_Stream& (CGAL_PS_Stream::*_PS_func)(T); T param; }; template CGAL_PS_Stream& operator<<(CGAL_PS_Stream& pss, const CGAL_PS_Modifier &m) { (pss.*m._PS_func)(m.param); return pss; }; template class CGAL_PS_Modifier_creator { public: CGAL_PS_Modifier_creator(CGAL_PS_Stream& (CGAL_PS_Stream::*f)(T)): _PS_func(f) {} CGAL_PS_Modifier operator() (T param) { return CGAL_PS_Modifier(_PS_func,param); } private: CGAL_PS_Stream& (CGAL_PS_Stream::*_PS_func)(T); }; #endif //CGAL_PS_MANIP_H_ @} \subsection{Implementation : The Catalogue} This function set the default context in the postscript stream. @$@+=@{@- void CGAL_PS_Stream::setdefault() { if (ctxt.get_border_color()!=CGAL_CTXT_DEFAULT.get_border_color()) os()<<"0 0 0 setrgbcolor"<+=@{@- void CGAL_PS_Stream::insert_catalogue() { if (is_eps()) { os() << "%!PS-Adobe-3.0 EPSF 3.0" << endl; os() << "%%BoundingBox: " << "0 0 " << width() << " " << height()<< endl; os() << "%%Creator: CGAL_PS_Stream" << endl; os() << "%%Title: (CGAL Output)" << endl; os() << "%%CreationDate:" << endl; } else { os() << "%!PS-Adobe-3.0" << endl; } os() << "%%EndComments" <+=@{@- CGAL_PS_Stream& CGAL_PS_Stream::_SetBorderColor(CGAL_Color &color) { if (ctxt.get_border_color()!=color) { os() << color.r() << " " << color.g() << " " << color.b() << " setrgbcolor" < > p) { ctxt.set_current_pos(p); return *this; } CGAL_PS_Stream& CGAL_PS_Stream::_ShowAxis(Axis &g) { static bool test=false; double x0=x2ps(0); double y0=y2ps(0); double i; if (!test) { os() << "gsave 0 setgray " << g.thickness() << " setlinewidth" << endl; os() << "[] 0 setdash" << endl; os() << x0 << " " << 0 << " mt" <+=@{@- #ifndef _PS_LABEL_ #define _PS_LABEL_ CGAL_PS_Stream &operator<<(CGAL_PS_Stream &ps, const CGAL_PS_Stream::Border &b) { ps.os() << "gsave" << endl; ps.os() << "0 setgray [] 0 setdash" << endl; ps.os() << b.size() << " setlinewidth" << endl; ps.os() << "0 0 " << ps.width() << " " << ps.height() << " rectstroke" << endl; ps.os() << "grestore" << endl; return ps; } CGAL_PS_Stream &operator<<(CGAL_PS_Stream &ps, const CGAL_PS_Stream::Label &txt) { ps.os() << ps.x2ps(ps.context().get_pos().x()) << " " << ps.y2ps(ps.context().get_pos().y()) << " mt" <+=@{@- #ifdef CGAL_POINT_2_H template < class R > CGAL_PS_Stream &operator<<(CGAL_PS_Stream &ps, const CGAL_Point_2 &p) { if (ps.is_readable()) { ps.os() << "%CGAL% Point" << endl; ps.os() << "%CGAL% "<+=@{@- #ifdef CGAL_SEGMENT_2_H template < class R > CGAL_PS_Stream &operator<<(CGAL_PS_Stream &ps, const CGAL_Segment_2 &s) { if (ps.is_readable()) { ps.os() << "%CGAL% Segment" << endl; ps.os() << "%CGAL% "<+=@{@- #ifdef CGAL_LINE_2_H template < class R > CGAL_PS_Stream &operator<<(CGAL_PS_Stream &ps, const CGAL_Line_2 &l) { if (ps.is_readable()) { ps.os() << "%CGAL% Line" << endl; ps.os() << "%CGAL% "<+=@{@- #ifdef CGAL_RAY_2_H template < class R > CGAL_PS_Stream &operator<<(CGAL_PS_Stream &ps, const CGAL_Ray_2 &r) { typedef CGAL_Direction_2 > dir; CGAL_Line_2 l=r.supporting_line(); dir haut(0,1); dir bas(0,-1); if (ps.is_readable()) { ps.os() << "%CGAL% Ray" << endl; ps.os() << "%CGAL% "<bas || r.direction()+=@{@- #ifdef CGAL_PARABOLA_2_H template < class R > CGAL_PS_Stream &operator<<(CGAL_PS_Stream &ps,const CGAL_Parabola &p) { if (ps.is_readable()) { ps.os() << "%CGAL% Parabola" << endl; ps.os() << "%CGAL% Base "<+=@{@- #ifdef CGAL_TRIANGLE_2_H template < class R > CGAL_PS_Stream &operator<<(CGAL_PS_Stream &ps,const CGAL_Triangle_2 &t) { if (ps.is_readable()) { ps.os() << "%CGAL% Triangle" << endl; for (int i=0;i<3;i++) ps.os() << "%CGAL " << t[i].x() << " " << t[i].y() << 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 " << endl; ps.os() << ps.context().get_fill_color().r() << " " << ps.context().get_fill_color().g() << " " << ps.context().get_fill_color().b() << " setcolor fill grestore " <+=@{@- #ifdef CGAL_ISO_RECTANGLE_2_H template < class R > CGAL_PS_Stream &operator<<(CGAL_PS_Stream &ps,const CGAL_Iso_rectangle_2 &r) { if (ps.is_readable()) { ps.os() << "%CGAL% Rectangle" << endl; for (int i=0;i<4;i++) ps.os() << "%CGAL " << r[i].x() << " " << r[i].y() << 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 " << endl; ps.os() << ps.context().get_fill_color().r() << " " << ps.context().get_fill_color().g() << " " << ps.context().get_fill_color().b() << " setcolor fill grestore " <+=@{@- #ifdef CGAL_CIRCLE_2_H template < class R > CGAL_PS_Stream &operator<<(CGAL_PS_Stream &ps, const CGAL_Circle_2 &c) { if (ps.is_readable()) { ps.os() << "%CGAL% Circle" << endl; ps.os() << "%CGAL " << c.center().x() << " " << c.center().y() << endl; ps.os() << "%CGAL " << c.squared_radius() << endl; } double ratio=ps.yratio()/ps.xratio(); ps.os()<< "gsave 1 " << ratio << " scale" << endl; ps.os()<< ps.x2ps(c.center().x()) << " " << ps.y2ps(c.center().y())/ratio << " " << c.squared_radius()*ps.xratio() << " 0 360 arc " << endl; if (ps.context().get_fill()) { ps.os() << "gsave " << endl; ps.os() << ps.context().get_fill_color().r() << " " << ps.context().get_fill_color().g() << " " << ps.context().get_fill_color().b() << " setcolor fill grestore " <==@{@- #include @ @ @ @ @} \subsection{The Header File} @O@<../include/CGAL/IO/Postscript_stream.h@>==@{@- #ifndef CGAL_Postscript_STREAM #define CGAL_Postscript_STREAM // For g++ compiler... // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include @ @ @ #endif // CGAL_Postscript_STREAM @} \end{document}