18#include "Board/Point.h"
19#include "Board/Rect.h"
20#include "Board/Shapes.h"
21#include "Board/Tools.h"
22#include "Board/PSFonts.h"
36#pragma clang diagnostic push
37#pragma clang diagnostic ignored "-Wdocumentation"
44#pragma clang diagnostic pop
51#define _USE_MATH_DEFINES
65#pragma warning(disable : 4290)
71#define _HAS_MSVC_MAX_ true
75#define _HAS_MSVC_MIN_ true
81 const float pageSizes[3][2] = { { 0.0f, 0.0f },
83 { 8.5f*25.4f, 11.0f*25.4f } };
84 const float ppmm = 720.0f / 254.0f;
111 _state( other._state ),
112 _backgroundColor( other._backgroundColor )
120 if ( ! other.
_shapes.size() )
return (*
this);
122 std::vector<Shape*>::iterator t =
_shapes.begin();
123 std::vector<Shape*>::const_iterator i = other.
_shapes.begin();
124 std::vector<Shape*>::const_iterator end = other.
_shapes.end();
211 return static_cast<const Board &
>(
Board( *this ).
rotate( angle, aCenter ) );
281 unsigned char alpha )
308 unsigned char alpha )
359 if ( depthValue != -1 )
371 if ( depthValue != -1 )
387 if ( depthValue != -1 )
404 if ( depthValue != -1 )
418 double width,
double height,
421 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
429 double width,
double height,
430 int depthValue,
double alpha )
432 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
434 filename, d, alpha ) );
440 double width,
double height,
443 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
454 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
462 bool neg,
int depthValue ){
463 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
475 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
483 double xRadius,
double yRadius,
486 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
498 double xRadius,
double yRadius,
501 int d = depthValue ? depthValue :
_nextDepth--;
514 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
515 std::vector<Point> v = points;
516 std::vector<Point>::iterator it = v.begin();
517 std::vector<Point>::iterator end = v.end();
518 while ( it != end ) {
534 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
535 std::vector<Point> v = points;
536 std::vector<Point>::iterator it = v.begin();
537 std::vector<Point>::iterator end = v.end();
538 while ( it != end ) {
554 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
555 std::vector<Point> v = points;
556 std::vector<Point>::iterator it = v.begin();
557 std::vector<Point>::iterator end = v.end();
558 while ( it != end ) {
572 double x2,
double y2,
573 double x3,
double y3,
576 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
577 std::vector<Point> points;
595 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
596 std::vector<Point> points;
610 double x2,
double y2,
611 double x3,
double y3,
614 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
615 std::vector<Point> points;
633 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
634 std::vector<Point> points;
653 unsigned char divisions,
656 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
665 const float brightness1,
667 const float brightness2,
669 const float brightness3,
670 unsigned char divisions,
676 color1.
red(
static_cast<unsigned char>( std::min( 255.0f, color1.
red() * brightness1 ) ) );
677 color1.
green(
static_cast<unsigned char>( std::min( 255.0f, color1.
green() * brightness1 ) ) );
678 color1.
blue(
static_cast<unsigned char>( std::min( 255.0f, color1.
blue() * brightness1 ) ) );
679 color2.
red(
static_cast<unsigned char>( std::min( 255.0f, color2.
red() * brightness2 ) ) );
680 color2.
green(
static_cast<unsigned char>( std::min( 255.0f, color2.
green() * brightness2 ) ) );
681 color2.
blue(
static_cast<unsigned char>( std::min( 255.0f, color2.
blue() * brightness2 ) ) );
682 color3.
red(
static_cast<unsigned char>( std::min( 255.0f, color3.
red() * brightness3 ) ) );
683 color3.
green(
static_cast<unsigned char>( std::min( 255.0f, color3.
green() * brightness3 ) ) );
684 color3.
blue(
static_cast<unsigned char>( std::min( 255.0f, color3.
blue() * brightness3 ) ) );
696 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
704 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
712 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
729 double rectWidth,
double rectHeight )
742 std::vector<Point>::const_iterator it = points.begin();
743 std::vector<Point>::const_iterator end = points.end();
744 while ( it != end ) {
760 for (
unsigned int i = 0; i < n; ++i ) {
769 double dx,
double dy,
double scaleValue )
774 if ( scaleValue != 1.0 )
775 s->
scale( scaleValue );
784 double dx,
double dy,
785 double scaleX,
double scaleY,
791 if ( scaleX != 1.0 || scaleY != 1.0 ) s->
scale( scaleX, scaleY );
792 if ( dx != 0.0 || dy != 0.0 ) s->
translate( dx, dy );
793 if ( angle != 0.0 ) s->
rotate( angle );
801 saveEPS( out, pageSizes[size][0], pageSizes[size][1], margin );
807 saveEPS( filename, pageSizes[size][0], pageSizes[size][1], margin );
812Board::saveEPS(
const char * filename,
double pageWidth,
double pageHeight,
double margin )
const
814 std::ofstream file( filename );
815 saveEPS(file, pageWidth, pageHeight, margin);
820Board::saveEPS( std::ostream &out,
double pageWidth,
double pageHeight,
double margin )
const
830 out <<
"%!PS-Adobe-2.0 EPSF-2.0" << std::endl;
831 out <<
"%%Title: output.eps " << std::endl;
832 out <<
"%%Creator: Board library (Copyleft)2007 Sebastien Fourey" << std::endl;
837 out <<
"%%CreationDate: " << str_time;
839 out <<
"%%BoundingBox: " << std::setprecision( 8 )
840 << transform.mapX( box.
left ) <<
" "
841 << transform.mapY( box.
top - box.
height ) <<
" "
842 << transform.mapX( box.
left + box.
width ) <<
" "
843 << transform.mapY( box.
top ) << std::endl;
845 out <<
"%Magnification: 1.0000" << std::endl;
846 out <<
"%%EndComments" << std::endl;
849 out <<
"/cp {closepath} bind def" << std::endl;
850 out <<
"/ef {eofill} bind def" << std::endl;
851 out <<
"/gr {grestore} bind def" << std::endl;
852 out <<
"/gs {gsave} bind def" << std::endl;
853 out <<
"/sa {save} bind def" << std::endl;
854 out <<
"/rs {restore} bind def" << std::endl;
855 out <<
"/l {lineto} bind def" << std::endl;
856 out <<
"/m {moveto} bind def" << std::endl;
857 out <<
"/rm {rmoveto} bind def" << std::endl;
858 out <<
"/n {newpath} bind def" << std::endl;
859 out <<
"/s {stroke} bind def" << std::endl;
860 out <<
"/sh {show} bind def" << std::endl;
861 out <<
"/slc {setlinecap} bind def" << std::endl;
862 out <<
"/slj {setlinejoin} bind def" << std::endl;
863 out <<
"/slw {setlinewidth} bind def" << std::endl;
864 out <<
"/srgb {setrgbcolor} bind def" << std::endl;
865 out <<
"/rot {rotate} bind def" << std::endl;
866 out <<
"/sc {scale} bind def" << std::endl;
867 out <<
"/sd {setdash} bind def" << std::endl;
868 out <<
"/ff {findfont} bind def" << std::endl;
869 out <<
"/sf {setfont} bind def" << std::endl;
870 out <<
"/scf {scalefont} bind def" << std::endl;
871 out <<
"/sw {stringwidth} bind def" << std::endl;
872 out <<
"/sd {setdash} bind def" << std::endl;
873 out <<
"/tr {translate} bind def" << std::endl;
874 out <<
" 0.5 setlinewidth" << std::endl;
879 out <<
" 0 slw clip " << std::endl;
885 r.flushPostscript( out, transform );
889 std::vector< Shape* > shapes =
_shapes;
892 std::vector< Shape* >::const_iterator i = shapes.begin();
893 std::vector< Shape* >::const_iterator end = shapes.end();
896 (*i)->flushPostscript( out, transform );
899 out <<
"showpage" << std::endl;
900 out <<
"%%Trailer" << std::endl;
901 out <<
"%EOF" << std::endl;
909 saveFIG( filename, pageSizes[size][0], pageSizes[size][1], margin, includeFIGHeader );
914 saveFIG( out, pageSizes[size][0], pageSizes[size][1], margin, includeFIGHeader );
917Board::saveFIG(
const char * filename,
double pageWidth,
double pageHeight,
double margin,
918 bool includeFIGHeader )
const
920 std::ofstream file( filename );
921 saveFIG( file, pageWidth, pageHeight, margin, includeFIGHeader);
926Board::saveFIG( std::ostream &file,
double pageWidth,
double pageHeight,
double margin,
bool includeFIGHeader )
const
932 transform.setBoundingBox( box, pageWidth, pageHeight, margin );
933 transform.setDepthRange( *
this );
934 if(includeFIGHeader){
935 file <<
"#FIG 3.2 Produced by the Board library (Copyleft)2007 Sebastien Fourey\n";
936 file <<
"Portrait\n";
947 std::map<DGtal::Color,int> colormap;
961 std::vector< Shape* > shapes =
_shapes;
963 std::vector< Shape* >::const_iterator i = shapes.begin();
964 std::vector< Shape* >::const_iterator end = shapes.end();
966 if ( colormap.find( (*i)->penColor() ) == colormap.end()
967 && (*i)->penColor().valid() )
968 colormap[ (*i)->penColor() ] = maxColor++;
969 if ( colormap.find( (*i)->fillColor() ) == colormap.end()
970 && (*i)->fillColor().valid() )
971 colormap[ (*i)->fillColor() ] = maxColor++;
980 std::map<DGtal::Color,int>::const_iterator iColormap = colormap.begin();
981 std::map<DGtal::Color,int>::const_iterator endColormap = colormap.end();
982 char colorString[255];
983 while ( iColormap != endColormap ) {
984 secured_sprintf( colorString, 255,
985 "0 %d #%02x%02x%02x\n",
987 iColormap->first.red(),
988 iColormap->first.green(),
989 iColormap->first.blue() );
990 if ( iColormap->second >= 32 ) file << colorString;
997 r.depth( std::numeric_limits<int>::max() );
998 r.flushFIG( file, transform, colormap );
1003 while ( i != end ) {
1005 (*i)->flushFIG( file, transform, colormap );
1014 saveSVG( filename, pageSizes[size][0], pageSizes[size][1], margin );
1020 saveSVG( out, pageSizes[size][0], pageSizes[size][1], margin );
1025Board::saveSVG(
const char * filename,
double pageWidth,
double pageHeight,
double margin )
const
1027 std::ofstream file( filename );
1028 saveSVG(file, pageWidth, pageHeight, margin);
1035Board::saveSVG( std::ostream &file,
double pageWidth,
double pageHeight,
double margin, std::string filename )
const
1043 transform.setBoundingBox( box, pageWidth, pageHeight, margin );
1045 file <<
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" standalone=\"no\"?>" << std::endl;
1046 file <<
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"" << std::endl;
1047 file <<
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">" << std::endl;
1049 if ( pageWidth > 0 && pageHeight > 0 ) {
1050 file <<
"<svg width=\""
1051 << pageWidth <<
"mm\" height=\""
1052 << pageHeight <<
"mm\" " << std::endl;
1053 file <<
" viewBox=\"0 0 "
1054 << pageWidth * ppmm <<
" "
1055 << pageHeight * ppmm <<
"\" " << std::endl;
1056 file <<
" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" >" << std::endl;
1058 file <<
"<svg width=\""
1059 << ( box.
width / ppmm ) <<
"mm"
1061 << ( box.
height / ppmm ) <<
"mm"
1062 <<
"\" " << std::endl;
1063 file <<
" viewBox=\"0 0 "
1065 << box.
height <<
"\" " << std::endl;
1066 file <<
" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" >" << std::endl;
1070 file <<
"<desc>" << filename
1071 <<
", created with the Board library (Copyleft) 2007 Sebastien Fourey"
1072 <<
"</desc>" << std::endl;
1075 file <<
"<g clip-rule=\"nonzero\">\n"
1076 <<
" <clipPath id=\"GlobalClipPath\">\n"
1077 <<
" <path clip-rule=\"evenodd\" d=\"";
1080 file <<
" </clipPath>\n";
1081 file <<
"<g clip-path=\"url(#GlobalClipPath)\">\n";
1087 r.flushSVG( file, transform );
1091 std::vector< Shape* > shapes =
_shapes;
1093 std::vector< Shape* >::const_iterator i = shapes.begin();
1094 std::vector< Shape* >::const_iterator end = shapes.end();
1095 while ( i != end ) {
1096 (*i)->flushSVG( file, transform );
1101 file <<
"</g>\n</g>";
1102 file <<
"</svg>" << std::endl;
1108Board::save(
const char * filename,
double pageWidth,
double pageHeight,
double margin )
const
1110 const char * extension = filename + strlen( filename );
1111 while ( extension > filename && *extension !=
'.' )
1113 if ( !(strcmp( extension,
".eps" )) || !(strcmp( extension,
".EPS" )) ) {
1114 saveEPS( filename, pageWidth, pageHeight, margin );
1117 if ( !(strcmp( extension,
".fig" )) || !(strcmp( extension,
".FIG" )) ) {
1118 saveFIG( filename, pageWidth, pageHeight, margin );
1121 if ( !(strcmp( extension,
".svg" )) || !(strcmp( extension,
".SVG" )) ) {
1122 saveSVG( filename, pageWidth, pageHeight, margin );
1125 if ( !(strcmp( extension,
".tikz" )) || !(strcmp( extension,
".TIKZ" )) ) {
1126 saveTikZ( filename, pageWidth, pageHeight, margin );
1134 save( filename, pageSizes[size][0], pageSizes[size][1], margin );
1141 saveCairo( filename, type, pageSizes[size][0], pageSizes[size][1], margin );
1146 cairo_surface_t *surface;
1149 double cairoWidth, cairoHeight;
1157 transform.setBoundingBox( box, pageWidth, pageHeight, margin );
1159 if ( pageWidth > 0 && pageHeight > 0 )
1161 cairoWidth = pageWidth;
1162 cairoHeight = pageHeight;
1166 cairoWidth = box.
width;
1167 cairoHeight = box.
height;
1173 surface = cairo_pdf_surface_create (filename, cairoWidth, cairoHeight);
break;
1175 surface = cairo_ps_surface_create (filename, cairoWidth, cairoHeight);
break;
1177 surface = cairo_ps_surface_create (filename, cairoWidth, cairoHeight);
1178 cairo_ps_surface_set_eps(surface,
true);
break;
1180 surface = cairo_svg_surface_create (filename, cairoWidth, cairoHeight);
break;
1183 surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, (
int)cairoWidth, (
int)cairoHeight);
1186 cr = cairo_create (surface);
1197 r.flushCairo( cr, transform );
1201 std::vector< Shape* > shapes =
_shapes;
1203 std::vector< Shape* >::const_iterator i = shapes.begin();
1204 std::vector< Shape* >::const_iterator end = shapes.end();
1205 while ( i != end ) {
1206 (*i)->flushCairo( cr, transform );
1211 cairo_surface_write_to_png (surface, filename);
1214 cairo_surface_destroy (surface);
1221 saveTikZ( filename, pageSizes[size][0], pageSizes[size][1], margin );
1227 saveTikZ( out, pageSizes[size][0], pageSizes[size][1], margin );
1233 std::ofstream file( filename );
1234 saveTikZ(file, pageHeight, pageHeight, margin);
1239Board::saveTikZ( std::ostream &out,
double pageWidth,
double pageHeight,
double margin )
const
1246 transform.setBoundingBox( box, pageWidth, pageHeight, margin );
1248 out <<
"\\begin{tikzpicture}[anchor=south west,text depth=0,x={(1pt,0pt)},y={(0pt,-1pt)}]" << std::endl;
1259 r.flushTikZ( out, transform );
1263 std::vector< Shape* > shapes =
_shapes;
1265 std::vector< Shape* >::const_iterator i = shapes.begin();
1266 std::vector< Shape* >::const_iterator end = shapes.end();
1267 while ( i != end ) {
1268 (*i)->flushTikZ( out, transform );
1274 out <<
"\\end{tikzpicture}" << std::endl;
Structure representing an RGB triple with alpha component.
Color & setRGBi(const unsigned char aRedValue, const unsigned char aGreenValue, const unsigned char aBlueValue, const unsigned char aAlphaValue=255)
void green(const unsigned char aGreenValue)
void red(const unsigned char aRedValue)
Color & setRGBf(float red, float green, float blue, float alpha=1.0)
void blue(const unsigned char aBlueValue)
Class for EPS, FIG or SVG drawings.
void drawRectangle(double x, double y, double width, double height, int depthValue=-1)
Board & setFont(const Fonts::Font font, double fontSize)
Board & setPenColor(const DGtal::Color &color)
void fillTriangle(double x1, double y1, double x2, double y2, double x3, double y3, int depthValue=-1)
void setClippingRectangle(double x, double y, double width, double height)
DGtal::Color _backgroundColor
void drawEllipse(double x, double y, double xRadius, double yRadius, int depthValue=-1)
void drawPolyline(const std::vector< Point > &points, int depthValue=-1)
Board & setFontSize(double fontSize)
void saveTikZ(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
void saveFIG(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0, bool includeFIGHeader=true) const
void setClippingPath(const std::vector< Point > &points)
Board & operator<<(const Shape &shape)
void drawTriangle(double x1, double y1, double x2, double y2, double x3, double y3, int depthValue=-1)
void drawQuadraticBezierCurve(double x1, double y1, double x2, double y2, double x3, double y3, int depthValue=-1)
void fillCircle(double x, double y, double radius, int depthValue=-1)
void drawLine(double x1, double y1, double x2, double y2, int depthValue=-1)
void fillPolyline(const std::vector< Point > &points, int depthValue=-1)
Board & operator=(const Board &other)
void save(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
Board & setPenColorRGBi(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha=255)
void drawDot(double x, double y, int depthValue=-1)
static const double Degree
void drawClosedPolyline(const std::vector< Point > &points, int depthValue=-1)
void drawArc(double x, double y, double radius, double angle1, double angle2, bool neg, int depthValue=-1)
void fillGouraudTriangle(const Point &p1, const DGtal::Color &color1, const Point &p2, const DGtal::Color &color2, const Point &p3, const DGtal::Color &color3, unsigned char divisions=3, int depthValue=-1)
void drawArrow(double x1, double y1, double x2, double y2, bool filled=true, int depthValue=-1)
Board & setPenColorRGBf(float red, float green, float blue, float alpha=1.0f)
void drawCircle(double x, double y, double radius, int depthValue=-1)
Shape & translate(double dx, double dy)
void fillRectangle(double x, double y, double width, double height, int depthValue=-1)
Board translated(double dx, double dy)
Shape & rotate(double angle, const Point ¢er)
void addDuplicates(const Shape &shape, unsigned int times, double dx, double dy, double scale=1.0)
Board scaled(double sx, double sy)
void drawText(double x, double y, const char *text, int depthValue=-1)
Board & setFillColorRGBi(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha=255)
Board & setFillColor(const DGtal::Color &color)
Board & setLineWidth(double width)
void fillEllipse(double x, double y, double xRadius, double yRadius, int depthValue=-1)
void saveEPS(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
void backgroundColor(const DGtal::Color &color)
void drawImage(std::string filename, double x, double y, double width, double height, int depthValue=-1, double alpha=1.0)
void saveSVG(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
Board & setFillColorRGBf(float red, float green, float blue, float alpha=1.0f)
Board(const DGtal::Color &backgroundColor=DGtal::Color::None)
Shape & scale(double sx, double sy)
Board rotated(double angle, const Point ¢er)
void drawBoundingBox(int depthValue=-1)
void saveCairo(const char *filename, CairoType type=CairoPNG, PageSize size=Board::BoundingBox, double margin=10.0) const
bool shapeGreaterDepth(const Shape *s1, const Shape *s2)
void secured_ctime(char *str, const time_t *t, size_t count)
A line between two points with an arrow at one extremity.
double unit(const double &x)
Shape::LineStyle lineStyle
A line between two points.
A triangle with shaded filling according to colors given for each vertex.
Used to draw image in figure.
A line between two points.
A path, according to Postscript and SVG definition.
unsigned int size() const
Path & scale(double sx, double sy)
void setClosed(bool closed)
Path & translate(double dx, double dy)
void flushPostscript(std::ostream &stream, const TransformEPS &transform) const
void flushSVGCommands(std::ostream &stream, const TransformSVG &transform) const
Path & rotate(double angle, const Point ¢er)
Struct representing a 2D point.
A polygonal line described by a series of 2D points.
A quadratic Bezier curve having 3 control points. NB. It is also a parabola arc.
Struct representing a rectangle on the plane.
void addShape(const Shape &shape, double scaleFactor)
Shape & rotate(double angle, const Point ¢er)
std::vector< Shape * > _shapes
Shape & translate(double dx, double dy)
Shape & scale(double sx, double sy)
Abstract structure for a 2D shape.
virtual Shape & scale(double sx, double sy)=0
virtual Shape & translate(double dx, double dy)=0
virtual Shape * clone() const =0
virtual Shape & rotate(double angle, const Point ¢er)=0