18#include "Board/Point.h"
19#include "Board/Rect.h"
20#include "Board/Tools.h"
21#include "Board/PSFonts.h"
32#ifdef DGTAL_WITH_CAIRO
35#pragma clang diagnostic push
36#pragma clang diagnostic ignored "-Wdocumentation"
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;
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 ) );
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 ) );
246 _state.unitFactor = 25.4f * ppmm;
249 _state.unitFactor = 10.0f * ppmm;
262 _state.unitFactor = factor;
265 _state.unitFactor = 720.0f * factor;
268 _state.unitFactor = 10.0f * ppmm * factor;
271 _state.unitFactor = ppmm * factor;
280 unsigned char alpha )
282 _state.penColor.setRGBi( red, green, blue, alpha );
292 _state.penColor.setRGBf( red, green, blue, alpha );
307 unsigned char alpha )
309 _state.fillColor.setRGBi( red, green, blue, alpha );
316 _state.fillColor.setRGBf( red, green, blue, alpha );
338 _state.fontSize = fontSize;
345 _state.fontSize = fontSize;
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--;
464 angle1, angle2, neg,
_state.penColor,
474 int d = (depthValue != -1) ? depthValue :
_nextDepth--;
477 0.0f,
_state.lineStyle, d ) );
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 ) {
518 (*it) =
_state.unit( *it );
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 ) {
538 (*it) =
_state.unit( *it );
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 ) {
558 (*it) =
_state.unit( *it );
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 );
775 s->translate( dx, dy );
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 );
800 saveEPS( out, pageSizes[size][0], pageSizes[size][1], margin );
806 saveEPS( filename, pageSizes[size][0], pageSizes[size][1], margin );
811Board::saveEPS(
const char * filename,
double pageWidth,
double pageHeight,
double margin )
const
813 std::ofstream file( filename );
814 saveEPS(file, pageWidth, pageHeight, margin);
811Board::saveEPS(
const char * filename,
double pageWidth,
double pageHeight,
double margin )
const {
…}
819Board::saveEPS( std::ostream &out,
double pageWidth,
double pageHeight,
double margin )
const
827 transform.setBoundingBox( box, pageWidth, pageHeight, margin );
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;
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;
819Board::saveEPS( std::ostream &out,
double pageWidth,
double pageHeight,
double margin )
const {
…}
908 saveFIG( filename, pageSizes[size][0], pageSizes[size][1], margin, includeFIGHeader );
913 saveFIG( out, pageSizes[size][0], pageSizes[size][1], margin, includeFIGHeader );
916Board::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);
916Board::saveFIG(
const char * filename,
double pageWidth,
double pageHeight,
double margin, {
…}
925Board::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;
996 r.
depth( std::numeric_limits<int>::max() );
997 r.
flushFIG( file, transform, colormap );
1002 while ( i != end ) {
1004 (*i)->flushFIG( file, transform, colormap );
925Board::saveFIG( std::ostream &file,
double pageWidth,
double pageHeight,
double margin,
bool includeFIGHeader )
const {
…}
1013 saveSVG( filename, pageSizes[size][0], pageSizes[size][1], margin );
1019 saveSVG( out, pageSizes[size][0], pageSizes[size][1], margin );
1024Board::saveSVG(
const char * filename,
double pageWidth,
double pageHeight,
double margin )
const
1026 std::ofstream file( filename );
1027 saveSVG(file, pageWidth, pageHeight, margin);
1024Board::saveSVG(
const char * filename,
double pageWidth,
double pageHeight,
double margin )
const {
…}
1034Board::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";
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;
1034Board::saveSVG( std::ostream &file,
double pageWidth,
double pageHeight,
double margin, std::string filename )
const {
…}
1107Board::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 );
1107Board::save(
const char * filename,
double pageWidth,
double pageHeight,
double margin )
const {
…}
1133 save( filename, pageSizes[size][0], pageSizes[size][1], margin );
1136#ifdef DGTAL_WITH_CAIRO
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);
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);
1238Board::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;
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;
1238Board::saveTikZ( std::ostream &out,
double pageWidth,
double pageHeight,
double margin )
const {
…}
Structure representing an RGB triple with alpha component.
void green(const unsigned char aGreenValue)
void red(const unsigned char aRedValue)
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.
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.
Struct representing a 2D point.
A polygonal line described by a series of 2D points.
void flushPostscript(std::ostream &stream, const TransformEPS &transform) const
A quadratic Bezier curve having 3 control points. NB. It is also a parabola arc.
Struct representing a rectangle on the plane.
void flushCairo(cairo_t *cr, const TransformCairo &transform) const
void flushTikZ(std::ostream &stream, const TransformTikZ &transform) const
void flushFIG(std::ostream &stream, const TransformFIG &transform, std::map< DGtal::Color, int > &colormap) const
void flushSVG(std::ostream &stream, const TransformSVG &transform) const
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 * clone() const =0
double angle(const DGtal::Z2i::RealPoint &point)
ImageContainerBySTLVector< Domain, Value > Image