18 #include "Board/Point.h"
19 #include "Board/Rect.h"
20 #include "Board/Tools.h"
21 #include "Board/PSFonts.h"
34 #if defined(__clang__)
35 #pragma clang diagnostic push
36 #pragma clang diagnostic ignored "-Wdocumentation"
39 #include <cairo-pdf.h>
41 #include <cairo-svg.h>
42 #if defined(__clang__)
43 #pragma clang diagnostic pop
50 #define _USE_MATH_DEFINES
64 #pragma warning(disable : 4290)
70 #define _HAS_MSVC_MAX_ true
74 #define _HAS_MSVC_MIN_ true
80 const float pageSizes[3][2] = { { 0.0f, 0.0f },
82 { 8.5f*25.4f, 11.0f*25.4f } };
83 const float ppmm = 720.0f / 254.0f;
110 _state( other._state ),
111 _backgroundColor( other._backgroundColor )
119 if ( ! other.
_shapes.size() )
return (*
this);
121 std::vector<Shape*>::iterator t =
_shapes.begin();
122 std::vector<Shape*>::const_iterator i = other.
_shapes.begin();
123 std::vector<Shape*>::const_iterator end = other.
_shapes.end();
210 return static_cast<const Board &
>(
Board( *this ).rotate( angle, aCenter ) );
216 return static_cast<const Board &
>(
Board( *this ).rotate( angle ) );
222 return static_cast<const Board &
>(
Board( *this ).translate( dx, dy ) );
228 return static_cast<const Board &
>(
Board( *this ).scale( sx, sy ) );
234 return static_cast<const Board &
>(
Board( *this ).scale( s ) );
280 unsigned char alpha )
307 unsigned char alpha )
358 if ( depthValue != -1 )
370 if ( depthValue != -1 )
386 if ( depthValue != -1 )
403 if ( depthValue != -1 )
417 double width,
double height,
420 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
428 double width,
double height,
429 int depthValue,
double alpha )
431 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
433 filename, d, alpha ) );
439 double width,
double height,
442 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
453 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
461 bool neg,
int depthValue ){
462 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
474 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
482 double xRadius,
double yRadius,
485 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
497 double xRadius,
double yRadius,
500 int d = depthValue ? depthValue :
_nextDepth--;
513 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
514 std::vector<Point> v = points;
515 std::vector<Point>::iterator it = v.begin();
516 std::vector<Point>::iterator end = v.end();
517 while ( it != end ) {
533 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
534 std::vector<Point> v = points;
535 std::vector<Point>::iterator it = v.begin();
536 std::vector<Point>::iterator end = v.end();
537 while ( it != end ) {
553 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
554 std::vector<Point> v = points;
555 std::vector<Point>::iterator it = v.begin();
556 std::vector<Point>::iterator end = v.end();
557 while ( it != end ) {
571 double x2,
double y2,
572 double x3,
double y3,
575 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
576 std::vector<Point> points;
594 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
595 std::vector<Point> points;
609 double x2,
double y2,
610 double x3,
double y3,
613 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
614 std::vector<Point> points;
632 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
633 std::vector<Point> points;
652 unsigned char divisions,
655 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
664 const float brightness1,
666 const float brightness2,
668 const float brightness3,
669 unsigned char divisions,
675 color1.
red(
static_cast<unsigned char>( std::min( 255.0f, color1.
red() * brightness1 ) ) );
676 color1.
green(
static_cast<unsigned char>( std::min( 255.0f, color1.
green() * brightness1 ) ) );
677 color1.
blue(
static_cast<unsigned char>( std::min( 255.0f, color1.
blue() * brightness1 ) ) );
678 color2.
red(
static_cast<unsigned char>( std::min( 255.0f, color2.
red() * brightness2 ) ) );
679 color2.
green(
static_cast<unsigned char>( std::min( 255.0f, color2.
green() * brightness2 ) ) );
680 color2.
blue(
static_cast<unsigned char>( std::min( 255.0f, color2.
blue() * brightness2 ) ) );
681 color3.
red(
static_cast<unsigned char>( std::min( 255.0f, color3.
red() * brightness3 ) ) );
682 color3.
green(
static_cast<unsigned char>( std::min( 255.0f, color3.
green() * brightness3 ) ) );
683 color3.
blue(
static_cast<unsigned char>( std::min( 255.0f, color3.
blue() * brightness3 ) ) );
695 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
703 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
711 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
728 double rectWidth,
double rectHeight )
741 std::vector<Point>::const_iterator it = points.begin();
742 std::vector<Point>::const_iterator end = points.end();
743 while ( it != end ) {
759 for (
unsigned int i = 0; i < n; ++i ) {
768 double dx,
double dy,
double scaleValue )
773 if ( scaleValue != 1.0 )
774 s->
scale( scaleValue );
783 double dx,
double dy,
784 double scaleX,
double scaleY,
790 if ( scaleX != 1.0 || scaleY != 1.0 ) s->
scale( scaleX, scaleY );
791 if ( dx != 0.0 || dy != 0.0 ) s->
translate( dx, dy );
792 if ( angle != 0.0 ) s->
rotate( angle );
800 saveEPS( out, pageSizes[size][0], pageSizes[size][1], margin );
806 saveEPS( filename, pageSizes[size][0], pageSizes[size][1], margin );
811 Board::saveEPS(
const char * filename,
double pageWidth,
double pageHeight,
double margin )
const
813 std::ofstream file( filename );
814 saveEPS(file, pageWidth, pageHeight, margin);
819 Board::saveEPS( std::ostream &out,
double pageWidth,
double pageHeight,
double margin )
const
829 out <<
"%!PS-Adobe-2.0 EPSF-2.0" << std::endl;
830 out <<
"%%Title: output.eps " << std::endl;
831 out <<
"%%Creator: Board library (Copyleft)2007 Sebastien Fourey" << std::endl;
836 out <<
"%%CreationDate: " << str_time;
838 out <<
"%%BoundingBox: " << std::setprecision( 8 )
839 << transform.mapX( box.
left ) <<
" "
840 << transform.mapY( box.
top - box.
height ) <<
" "
841 << transform.mapX( box.
left + box.
width ) <<
" "
842 << transform.mapY( box.
top ) << std::endl;
844 out <<
"%Magnification: 1.0000" << std::endl;
845 out <<
"%%EndComments" << std::endl;
848 out <<
"/cp {closepath} bind def" << std::endl;
849 out <<
"/ef {eofill} bind def" << std::endl;
850 out <<
"/gr {grestore} bind def" << std::endl;
851 out <<
"/gs {gsave} bind def" << std::endl;
852 out <<
"/sa {save} bind def" << std::endl;
853 out <<
"/rs {restore} bind def" << std::endl;
854 out <<
"/l {lineto} bind def" << std::endl;
855 out <<
"/m {moveto} bind def" << std::endl;
856 out <<
"/rm {rmoveto} bind def" << std::endl;
857 out <<
"/n {newpath} bind def" << std::endl;
858 out <<
"/s {stroke} bind def" << std::endl;
859 out <<
"/sh {show} bind def" << std::endl;
860 out <<
"/slc {setlinecap} bind def" << std::endl;
861 out <<
"/slj {setlinejoin} bind def" << std::endl;
862 out <<
"/slw {setlinewidth} bind def" << std::endl;
863 out <<
"/srgb {setrgbcolor} bind def" << std::endl;
864 out <<
"/rot {rotate} bind def" << std::endl;
865 out <<
"/sc {scale} bind def" << std::endl;
866 out <<
"/sd {setdash} bind def" << std::endl;
867 out <<
"/ff {findfont} bind def" << std::endl;
868 out <<
"/sf {setfont} bind def" << std::endl;
869 out <<
"/scf {scalefont} bind def" << std::endl;
870 out <<
"/sw {stringwidth} bind def" << std::endl;
871 out <<
"/sd {setdash} bind def" << std::endl;
872 out <<
"/tr {translate} bind def" << std::endl;
873 out <<
" 0.5 setlinewidth" << std::endl;
878 out <<
" 0 slw clip " << std::endl;
884 r.flushPostscript( out, transform );
888 std::vector< Shape* > shapes =
_shapes;
891 std::vector< Shape* >::const_iterator i = shapes.begin();
892 std::vector< Shape* >::const_iterator end = shapes.end();
895 (*i)->flushPostscript( out, transform );
898 out <<
"showpage" << std::endl;
899 out <<
"%%Trailer" << std::endl;
900 out <<
"%EOF" << std::endl;
908 saveFIG( filename, pageSizes[size][0], pageSizes[size][1], margin, includeFIGHeader );
913 saveFIG( out, pageSizes[size][0], pageSizes[size][1], margin, includeFIGHeader );
916 Board::saveFIG(
const char * filename,
double pageWidth,
double pageHeight,
double margin,
917 bool includeFIGHeader )
const
919 std::ofstream file( filename );
920 saveFIG( file, pageWidth, pageHeight, margin, includeFIGHeader);
925 Board::saveFIG( std::ostream &file,
double pageWidth,
double pageHeight,
double margin,
bool includeFIGHeader )
const
931 transform.setBoundingBox( box, pageWidth, pageHeight, margin );
932 transform.setDepthRange( *
this );
933 if(includeFIGHeader){
934 file <<
"#FIG 3.2 Produced by the Board library (Copyleft)2007 Sebastien Fourey\n";
935 file <<
"Portrait\n";
946 std::map<DGtal::Color,int> colormap;
960 std::vector< Shape* > shapes =
_shapes;
962 std::vector< Shape* >::const_iterator i = shapes.begin();
963 std::vector< Shape* >::const_iterator end = shapes.end();
965 if ( colormap.find( (*i)->penColor() ) == colormap.end()
966 && (*i)->penColor().valid() )
967 colormap[ (*i)->penColor() ] = maxColor++;
968 if ( colormap.find( (*i)->fillColor() ) == colormap.end()
969 && (*i)->fillColor().valid() )
970 colormap[ (*i)->fillColor() ] = maxColor++;
979 std::map<DGtal::Color,int>::const_iterator iColormap = colormap.begin();
980 std::map<DGtal::Color,int>::const_iterator endColormap = colormap.end();
981 char colorString[255];
982 while ( iColormap != endColormap ) {
983 secured_sprintf( colorString, 255,
984 "0 %d #%02x%02x%02x\n",
986 iColormap->first.red(),
987 iColormap->first.green(),
988 iColormap->first.blue() );
989 if ( iColormap->second >= 32 ) file << colorString;
997 r.flushFIG( file, transform, colormap );
1002 while ( i != end ) {
1004 (*i)->flushFIG( file, transform, colormap );
1013 saveSVG( filename, pageSizes[size][0], pageSizes[size][1], margin );
1019 saveSVG( out, pageSizes[size][0], pageSizes[size][1], margin );
1024 Board::saveSVG(
const char * filename,
double pageWidth,
double pageHeight,
double margin )
const
1026 std::ofstream file( filename );
1027 saveSVG(file, pageWidth, pageHeight, margin);
1034 Board::saveSVG( std::ostream &file,
double pageWidth,
double pageHeight,
double margin, std::string filename )
const
1042 transform.setBoundingBox( box, pageWidth, pageHeight, margin );
1044 file <<
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\" standalone=\"no\"?>" << std::endl;
1045 file <<
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"" << std::endl;
1046 file <<
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">" << std::endl;
1048 if ( pageWidth > 0 && pageHeight > 0 ) {
1049 file <<
"<svg width=\""
1050 << pageWidth <<
"mm\" height=\""
1051 << pageHeight <<
"mm\" " << std::endl;
1052 file <<
" viewBox=\"0 0 "
1053 << pageWidth * ppmm <<
" "
1054 << pageHeight * ppmm <<
"\" " << std::endl;
1055 file <<
" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" >" << std::endl;
1057 file <<
"<svg width=\""
1058 << ( box.
width / ppmm ) <<
"mm"
1060 << ( box.
height / ppmm ) <<
"mm"
1061 <<
"\" " << std::endl;
1062 file <<
" viewBox=\"0 0 "
1064 << box.
height <<
"\" " << std::endl;
1065 file <<
" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" >" << std::endl;
1069 file <<
"<desc>" << filename
1070 <<
", created with the Board library (Copyleft) 2007 Sebastien Fourey"
1071 <<
"</desc>" << std::endl;
1074 file <<
"<g clip-rule=\"nonzero\">\n"
1075 <<
" <clipPath id=\"GlobalClipPath\">\n"
1076 <<
" <path clip-rule=\"evenodd\" d=\"";
1079 file <<
" </clipPath>\n";
1080 file <<
"<g clip-path=\"url(#GlobalClipPath)\">\n";
1086 r.flushSVG( file, transform );
1090 std::vector< Shape* > shapes =
_shapes;
1092 std::vector< Shape* >::const_iterator i = shapes.begin();
1093 std::vector< Shape* >::const_iterator end = shapes.end();
1094 while ( i != end ) {
1095 (*i)->flushSVG( file, transform );
1100 file <<
"</g>\n</g>";
1101 file <<
"</svg>" << std::endl;
1107 Board::save(
const char * filename,
double pageWidth,
double pageHeight,
double margin )
const
1109 const char * extension = filename + strlen( filename );
1110 while ( extension > filename && *extension !=
'.' )
1112 if ( !(strcmp( extension,
".eps" )) || !(strcmp( extension,
".EPS" )) ) {
1113 saveEPS( filename, pageWidth, pageHeight, margin );
1116 if ( !(strcmp( extension,
".fig" )) || !(strcmp( extension,
".FIG" )) ) {
1117 saveFIG( filename, pageWidth, pageHeight, margin );
1120 if ( !(strcmp( extension,
".svg" )) || !(strcmp( extension,
".SVG" )) ) {
1121 saveSVG( filename, pageWidth, pageHeight, margin );
1124 if ( !(strcmp( extension,
".tikz" )) || !(strcmp( extension,
".TIKZ" )) ) {
1125 saveTikZ( filename, pageWidth, pageHeight, margin );
1133 save( filename, pageSizes[size][0], pageSizes[size][1], margin );
1140 saveCairo( filename, type, pageSizes[size][0], pageSizes[size][1], margin );
1148 double cairoWidth, cairoHeight;
1156 transform.setBoundingBox( box, pageWidth, pageHeight, margin );
1158 if ( pageWidth > 0 && pageHeight > 0 )
1160 cairoWidth = pageWidth;
1161 cairoHeight = pageHeight;
1165 cairoWidth = box.
width;
1166 cairoHeight = box.
height;
1172 surface = cairo_pdf_surface_create (filename, cairoWidth, cairoHeight);
break;
1174 surface = cairo_ps_surface_create (filename, cairoWidth, cairoHeight);
break;
1176 surface = cairo_ps_surface_create (filename, cairoWidth, cairoHeight);
1177 cairo_ps_surface_set_eps(
surface,
true);
break;
1179 surface = cairo_svg_surface_create (filename, cairoWidth, cairoHeight);
break;
1182 surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, (
int)cairoWidth, (
int)cairoHeight);
1196 r.flushCairo( cr, transform );
1200 std::vector< Shape* > shapes =
_shapes;
1202 std::vector< Shape* >::const_iterator i = shapes.begin();
1203 std::vector< Shape* >::const_iterator end = shapes.end();
1204 while ( i != end ) {
1205 (*i)->flushCairo( cr, transform );
1210 cairo_surface_write_to_png (
surface, filename);
1213 cairo_surface_destroy (
surface);
1220 saveTikZ( filename, pageSizes[size][0], pageSizes[size][1], margin );
1226 saveTikZ( out, pageSizes[size][0], pageSizes[size][1], margin );
1232 std::ofstream file( filename );
1233 saveTikZ(file, pageHeight, pageHeight, margin);
1238 Board::saveTikZ( std::ostream &out,
double pageWidth,
double pageHeight,
double margin )
const
1245 transform.setBoundingBox( box, pageWidth, pageHeight, margin );
1247 out <<
"\\begin{tikzpicture}[anchor=south west,text depth=0,x={(1pt,0pt)},y={(0pt,-1pt)}]" << std::endl;
1258 r.flushTikZ( out, transform );
1262 std::vector< Shape* > shapes =
_shapes;
1264 std::vector< Shape* >::const_iterator i = shapes.begin();
1265 std::vector< Shape* >::const_iterator end = shapes.end();
1266 while ( i != end ) {
1267 (*i)->flushTikZ( out, transform );
1273 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
CountedPtr< SH3::DigitalSurface > surface
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.
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 & translate(double dx, double dy)=0
virtual Shape & scale(double sx, double sy)=0
virtual Shape * clone() const =0
virtual Shape & rotate(double angle, const Point ¢er)=0
ImageContainerBySTLVector< Domain, Value > Image