mirror of https://github.com/CGAL/cgal
688 lines
19 KiB
C++
688 lines
19 KiB
C++
// 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.
|
|
//
|
|
// $Source$
|
|
// $Revision$ $Date$
|
|
// $Name$
|
|
//
|
|
// Author(s) :
|
|
|
|
#ifndef CGAL_IO_PS_STREAM_H
|
|
#define CGAL_IO_PS_STREAM_H
|
|
|
|
#include <CGAL/basic.h>
|
|
|
|
#include <cstdlib>
|
|
#include <cstdio>
|
|
#include <string>
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <fcntl.h>
|
|
#include <fstream>
|
|
#include <strstream>
|
|
#include <iterator>
|
|
#include <list>
|
|
|
|
#include <CGAL/Cartesian.h>
|
|
#include <CGAL/IO/Color.h>
|
|
#include <CGAL/Point_2.h>
|
|
#include <CGAL/Direction_2.h>
|
|
#include <CGAL/Bbox_2.h>
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
class PS_Stream;
|
|
|
|
template <class T>
|
|
class PS_Manipulator {
|
|
friend PS_Stream& operator<< <> (PS_Stream& , const PS_Manipulator<T> &);
|
|
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 <class T>
|
|
PS_Stream& operator << (PS_Stream& pss, const PS_Manipulator<T> &m)
|
|
{
|
|
(pss.*m._PS_func)(m.param);
|
|
return pss;
|
|
}
|
|
|
|
template<class T>
|
|
class PS_Manipulator_creator {
|
|
public:
|
|
PS_Manipulator_creator(PS_Stream& (PS_Stream::*f)(T)):
|
|
_PS_func(f) {}
|
|
PS_Manipulator<T> operator() (T param)
|
|
{
|
|
return PS_Manipulator<T>(_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<Latex_Label> 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<Cartesian <double> > (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<Cartesian <double> > 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<Cartesian <double> >& 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<Cartesian <double> > _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 <double> >);
|
|
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<const Color&> fill_color;
|
|
|
|
extern PS_Manipulator_creator<const Color&> border_color;
|
|
|
|
extern PS_Manipulator_creator<unsigned int> point_size;
|
|
|
|
extern PS_Manipulator_creator<PS_Stream::DotStyle> point_style;
|
|
|
|
extern PS_Manipulator_creator<DashStyle> line_style;
|
|
|
|
extern PS_Manipulator_creator<unsigned int> line_width;
|
|
|
|
extern PS_Manipulator_creator<bool> fill;
|
|
|
|
extern PS_Manipulator_creator<const PS_Stream::Context&> current_context;
|
|
|
|
extern PS_Manipulator_creator<Point_2< Cartesian <double> > > move_to;
|
|
|
|
extern PS_Manipulator_creator<PS_Stream::Axis&> show_axis;
|
|
|
|
extern PS_Manipulator_creator<PS_Stream::Grid&> show_grid;
|
|
|
|
extern PS_Manipulator_creator<const char*> ps_label;
|
|
|
|
extern PS_Manipulator_creator<const char*> latex_label;
|
|
|
|
extern PS_Manipulator_creator<unsigned int> border;
|
|
|
|
extern PS_Manipulator_creator<const char*> font;
|
|
|
|
extern PS_Manipulator_creator<unsigned int> font_size;
|
|
|
|
|
|
|
|
#ifdef CGAL_POINT_2_H
|
|
|
|
template < class R >
|
|
PS_Stream & operator <<(PS_Stream& ps, const Point_2<R>& p)
|
|
{
|
|
|
|
if (ps.is_readable())
|
|
{
|
|
ps.os() << "%CGAL% Point" << std::endl;
|
|
ps.os() << "%CGAL% "<<p.x()<<" "<<p.y()<<std::endl;
|
|
}
|
|
if (ps.context().get_dot_style()!=PS_Stream::NONE)
|
|
{
|
|
ps.os() << ps.x2ps(p.x()) << " "
|
|
<< ps.y2ps(p.y()) << " "
|
|
<< ps.context().get_dot_size() << " ";
|
|
|
|
switch (ps.context().get_dot_style())
|
|
{
|
|
case PS_Stream::EBOX:
|
|
ps.os() << "eb" << std::endl;
|
|
break;
|
|
case PS_Stream::FBOX:
|
|
ps.os() << "fb" << std::endl;
|
|
break;
|
|
case PS_Stream::EDOT:
|
|
ps.os() << "ec" << std::endl;
|
|
break;
|
|
case PS_Stream::FDOT:
|
|
ps.os() << "fc" << std::endl;
|
|
break;
|
|
case PS_Stream::ICROSS:
|
|
ps.os() << "ic" << std::endl;
|
|
break;
|
|
default :
|
|
ps.os() << "xc" << std::endl;
|
|
break;
|
|
}
|
|
}
|
|
|
|
else {
|
|
ps.os() << ps.x2ps(p.x()) << " "
|
|
<< ps.y2ps(p.y())<< " " ;
|
|
}
|
|
return ps;
|
|
}
|
|
|
|
#endif // CGAL_POINT_2_H
|
|
#ifdef CGAL_SEGMENT_2_H
|
|
|
|
template < class R >
|
|
PS_Stream & operator <<(PS_Stream& ps, const Segment_2<R>& s)
|
|
{
|
|
if (ps.is_readable())
|
|
{
|
|
ps.os() << "%CGAL% Segment" << std::endl;
|
|
ps.os() << "%CGAL% "<<s.source().x()<<" "<<s.source().y()<<" "
|
|
<<s.target().x()<<" "<<s.target().y()<<std::endl;
|
|
}
|
|
ps.os() << ps.x2ps(s.source().x()) << " "
|
|
<< ps.y2ps(s.source().y()) << " mt ";
|
|
ps.os() << ps.x2ps(s.target().x()) << " "
|
|
<< ps.y2ps(s.target().y())
|
|
<< " lt st" << std::endl;
|
|
|
|
return ps;
|
|
}
|
|
|
|
#endif // CGAL_SEGMENT_2_H
|
|
#ifdef CGAL_LINE_2_H
|
|
|
|
template < class R >
|
|
PS_Stream & operator <<(PS_Stream& ps, const Line_2<R>& l)
|
|
{
|
|
if (ps.is_readable())
|
|
{
|
|
ps.os() << "%CGAL% Line" << std::endl;
|
|
ps.os() << "%CGAL% "<<l.a()<<" "<<l.b()<<" "<<l.c()<<std::endl;
|
|
}
|
|
if (!l.is_degenerate())
|
|
if (l.is_vertical())
|
|
{
|
|
double t=ps.x2ps(l.x_at_y(0));
|
|
ps.os()<< t;
|
|
ps.os()<< " 0 mt" << std::endl;
|
|
ps.os()<< t << " " << ps.height() << " lt st" <<std::endl;
|
|
}
|
|
else
|
|
{
|
|
ps.os() << "0 "
|
|
<< ps.y2ps(l.y_at_x(ps.bbox().xmin()))
|
|
<< " mt" << std::endl;
|
|
ps.os() << ps.width() << " "
|
|
<< ps.y2ps(l.y_at_x(ps.bbox().xmax()))
|
|
<< " lt st"<< std::endl;
|
|
}
|
|
return ps;
|
|
}
|
|
|
|
#endif // CGAL_LINE_2_H
|
|
#ifdef CGAL_RAY_2_H
|
|
|
|
template < class R >
|
|
PS_Stream & operator <<(PS_Stream& ps, const Ray_2<R>& r)
|
|
{
|
|
typedef Direction_2<Cartesian <double> > dir;
|
|
Line_2<R> 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% "<<r.source().x()<<" "<<r.source().y()<<" ";
|
|
ps.os() << r.second_point().x() << " " << r.second_point().y();
|
|
ps.os() << std::endl;
|
|
}
|
|
if (!r.is_degenerate())
|
|
{
|
|
ps.os()<< ps.x2ps(r.source().x()) << " "
|
|
<< ps.y2ps(r.source().y()) << " mt" << std::endl;
|
|
if (r.is_vertical())
|
|
{
|
|
ps.os()<< ps.x2ps(r.source().x()) << " ";
|
|
if (r.direction()==haut)
|
|
ps.os() << ps.height();
|
|
else
|
|
ps.os() << "0 ";
|
|
ps.os() << " lt st" << std::endl;
|
|
}
|
|
else
|
|
if (r.direction()>bas || r.direction()<haut)
|
|
ps.os() << ps.width()
|
|
<< " "
|
|
<<ps.y2ps(l.y_at_x(ps.bbox().xmax()))
|
|
<< " lt st" << std::endl;
|
|
else
|
|
ps.os() << "0 "
|
|
<< ps.y2ps(l.y_at_x(ps.bbox().xmin()))
|
|
<< " lt st" << std::endl;
|
|
}
|
|
return ps;
|
|
}
|
|
|
|
#endif // CGAL_RAY_2_H
|
|
#ifdef CGAL_PARABOLA_2_H
|
|
|
|
template < class R >
|
|
PS_Stream & operator <<(PS_Stream& ps,const Parabola<R>& p)
|
|
{
|
|
|
|
if (ps.is_readable())
|
|
{
|
|
ps.os() << "%CGAL% Parabola" << std::endl;
|
|
ps.os() << "%CGAL% Base "<<p.base().x()<<" "<<p.base().y()<<std::endl;
|
|
ps.os() << "%CGAL% Vector " << p.vertor().x() << " " << p.vector().y()
|
|
<< std::endl;
|
|
ps.os() << "%CGAL% Curvature "<<p.curvature()<<std::endl;
|
|
}
|
|
return ps;
|
|
}
|
|
|
|
#endif // CGAL_PARABOLA_2_H
|
|
#ifdef CGAL_TRIANGLE_2_H
|
|
|
|
template < class R >
|
|
PS_Stream & operator <<(PS_Stream& ps,const Triangle_2<R>& 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 " <<std::endl;
|
|
}
|
|
ps.os() << "st" <<std::endl;
|
|
return ps;
|
|
}
|
|
|
|
#endif // CGAL_TRIANGLE_2_H
|
|
#ifdef CGAL_ISO_RECTANGLE_2_H
|
|
|
|
template < class R >
|
|
PS_Stream & operator <<(PS_Stream& ps,const Iso_rectangle_2<R>& 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 " <<std::endl;
|
|
}
|
|
ps.os() << "st" <<std::endl;
|
|
return ps;
|
|
}
|
|
|
|
#endif // CGAL_ISO_RECTANGLE_2_H
|
|
#ifdef CGAL_CIRCLE_2_H
|
|
|
|
template < class R >
|
|
PS_Stream & operator <<(PS_Stream& ps, const Circle_2<R>& c)
|
|
{
|
|
if (ps.is_readable())
|
|
{
|
|
ps.os() << "%CGAL% Circle" << std::endl;
|
|
ps.os() << "%CGAL " << c.center().x()<<" "<<c.center().y()<< std::endl;
|
|
ps.os() << "%CGAL " << c.squared_radius() << std::endl;
|
|
}
|
|
double ratio=ps.yratio()/ps.xratio();
|
|
double radius=sqrt(to_double(c.squared_radius()));
|
|
ps.os()<< "gsave 1 " << ratio << " scale" << std::endl;
|
|
ps.os()<< ps.x2ps(c.center().x()) << " " << ps.y2ps(c.center().y())/ratio
|
|
<< " " << radius*ps.xratio() << " 0 360 arc " << std::endl;
|
|
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 " <<std::endl;
|
|
}
|
|
ps.os() << "st grestore" <<std::endl;
|
|
return ps;
|
|
}
|
|
|
|
#endif // CGAL_CIRCLE_2_H
|
|
|
|
CGAL_END_NAMESPACE
|
|
|
|
#endif // CGAL_IO_PS_STREAM_H
|