DGtal  1.2.0
Board.cpp
1 /* -*- mode: c++ -*- */
10 /*
11  * \@copyright This File is part of the Board library which is
12  * licensed under the terms of the GNU Lesser General Public Licence.
13  * See the LICENCE file for further details.
14  */
15 
16 
17 #include "Board.h"
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"
23 #include <fstream>
24 #include <iostream>
25 #include <iomanip>
26 #include <typeinfo>
27 #include <ctime>
28 #include <cstring>
29 #include <map>
30 #include <algorithm>
31 #include <cstdio>
32 
33 #ifdef WITH_CAIRO
34 // cairo
35 #if defined(__clang__)
36 #pragma clang diagnostic push
37 #pragma clang diagnostic ignored "-Wdocumentation"
38 #endif
39 #include <cairo.h>
40 #include <cairo-pdf.h>
41 #include <cairo-ps.h>
42 #include <cairo-svg.h>
43 #if defined(__clang__)
44 #pragma clang diagnostic pop
45 #endif
46 // cairo
47 #endif
48 
49 
50 #if defined( WIN32 )
51 #define _USE_MATH_DEFINES
52 #include <math.h>
53 #else
54 #include <cmath>
55 #endif //win32
56 
57 #ifdef _MSC_VER
58 //#define NOMINMAX
59 //#include <windows.h>
60 //#ifdef M_PI
61 //#undef M_PI
62 //#endif
63 //C++ exception specification ignored except
64 //to indicate a function is not __declspec(nothrow)
65 #pragma warning(disable : 4290)
66 #endif
67 
68 #ifdef _MSC_VER
69 #if defined( max )
70 #undef max
71 #define _HAS_MSVC_MAX_ true
72 #endif
73 #if defined( min )
74 #undef min
75 #define _HAS_MSVC_MIN_ true
76 #endif
77 #endif
78 
79 
80 namespace {
81  const float pageSizes[3][2] = { { 0.0f, 0.0f }, // BoundingBox
82  { 210.0f, 297.0f },
83  { 8.5f*25.4f, 11.0f*25.4f } };
84  const float ppmm = 720.0f / 254.0f;
85 }
86 
87 namespace LibBoard {
88 
89 const double Board::Degree = 3.14159265358979323846 / 180.0;
90 
92 {
95  lineWidth = 0.5;
100  fontSize = 11.0;
101  unitFactor = 1.0;
102 }
103 
104 Board::Board( const DGtal::Color & bgColor )
105  : _backgroundColor( bgColor )
106 {
107 }
108 
109 Board::Board( const Board & other )
110  : ShapeList( other ),
111  _state( other._state ),
112  _backgroundColor( other._backgroundColor )
113 {
114 }
115 
116 Board &
117 Board::operator=( const Board & other )
118 {
119  free();
120  if ( ! other._shapes.size() ) return (*this);
121  _shapes.resize( other._shapes.size(), 0 );
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();
125  while ( i != end ) {
126  *t = (*i)->clone();
127  ++i; ++t;
128  }
129  return *this;
130 }
131 
133 Board::operator<<( const Shape & shape )
134 {
136  return *this;
137 }
138 
140 Board::operator<<( Unit unit )
141 {
142  setUnit( unit );
143  return *this;
144 }
145 
147 {
148 
149 }
150 
151 void
152 Board::clear( const DGtal::Color & color )
153 {
155  _backgroundColor = color;
156 }
157 
158 
159 Shape &
160 Board::rotate( double angle, const Point & aCenter )
161 {
162  ShapeList::rotate( angle, aCenter );
163  _clippingPath.rotate( angle, aCenter );
164  return (*this);
165 }
166 
167 Shape &
168 Board::rotate( double angle )
169 {
170  ShapeList::rotate( angle );
171  _clippingPath.rotate( angle, center() );
172  return (*this);
173 }
174 
175 Shape &
176 Board::translate( double dx, double dy )
177 {
178  ShapeList::translate( dx, dy );
179  _clippingPath.translate( dx, dy );
180  return (*this);
181 }
182 
183 Shape &
184 Board::scale( double sx, double sy )
185 {
186  Point delta = _clippingPath.center() - center();
187  delta.x *= sx;
188  delta.y *= sy;
189  _clippingPath.scale( sx, sy );
190  ShapeList::scale( sx, sy );
191  delta = ( center() + delta ) - _clippingPath.center();
192  _clippingPath.translate( delta.x, delta.y );
193  return (*this);
194 }
195 
196 Shape &
197 Board::scale( double s )
198 {
199  Point delta = _clippingPath.center() - center();
200  delta *= s;
201  _clippingPath.scale( s );
202  ShapeList::scale( s );
203  delta = ( center() + delta ) - _clippingPath.center();
204  _clippingPath.translate( delta.x, delta.y );
205  return (*this);
206 }
207 
208 Board
209 Board::rotated( double angle, const Point & aCenter )
210 {
211  return static_cast<const Board &>( Board( *this ).rotate( angle, aCenter ) );
212 }
213 
214 Board
215 Board::rotated( double angle )
216 {
217  return static_cast<const Board &>( Board( *this ).rotate( angle ) );
218 }
219 
220 Board
221 Board::translated( double dx, double dy )
222 {
223  return static_cast<const Board &>( Board( *this ).translate( dx, dy ) );
224 }
225 
226 Board
227 Board::scaled( double sx, double sy )
228 {
229  return static_cast<const Board &>( Board( *this ).scale( sx, sy ) );
230 }
231 
232 Board
233 Board::scaled( double s )
234 {
235  return static_cast<const Board &>( Board( *this ).scale( s ) );
236 }
237 
238 
239 void
241 {
242  switch ( unit ) {
243  case UPoint:
244  _state.unitFactor = 1.0;
245  break;
246  case UInche:
247  _state.unitFactor = 25.4f * ppmm;
248  break;
249  case UCentimeter:
250  _state.unitFactor = 10.0f * ppmm;
251  break;
252  case UMillimeter:
253  _state.unitFactor = ppmm;
254  break;
255  }
256 }
257 
258 void
259 Board::setUnit( double factor, Unit unit )
260 {
261  switch ( unit ) {
262  case UPoint:
263  _state.unitFactor = factor;
264  break;
265  case UInche:
266  _state.unitFactor = 720.0f * factor;
267  break;
268  case UCentimeter:
269  _state.unitFactor = 10.0f * ppmm * factor;
270  break;
271  case UMillimeter:
272  _state.unitFactor = ppmm * factor;
273  break;
274  }
275 }
276 
277 Board &
278 Board::setPenColorRGBi( unsigned char red,
279  unsigned char green,
280  unsigned char blue,
281  unsigned char alpha )
282 {
283  _state.penColor.setRGBi( red, green, blue, alpha );
284  return *this;
285 }
286 
287 Board &
289  float green,
290  float blue,
291  float alpha )
292 {
293  _state.penColor.setRGBf( red, green, blue, alpha );
294  return *this;
295 }
296 
297 Board &
299 {
300  _state.penColor = color;
301  return *this;
302 }
303 
304 Board &
305 Board::setFillColorRGBi( unsigned char red,
306  unsigned char green,
307  unsigned char blue,
308  unsigned char alpha )
309 {
310  _state.fillColor.setRGBi( red, green, blue, alpha );
311  return *this;
312 }
313 
314 Board &
315 Board::setFillColorRGBf( float red, float green, float blue, float alpha )
316 {
317  _state.fillColor.setRGBf( red, green, blue, alpha );
318  return *this;
319 }
320 
321 Board &
323 {
324  _state.fillColor = color;
325  return *this;
326 }
327 
328 Board &
329 Board::setLineWidth( double width )
330 {
331  _state.lineWidth = width;
332  return *this;
333 }
334 
335 Board &
336 Board::setFont( const Fonts::Font font, double fontSize )
337 {
338  _state.font = font;
339  _state.fontSize = fontSize;
340  return *this;
341 }
342 
343 Board &
344 Board::setFontSize( double fontSize )
345 {
346  _state.fontSize = fontSize;
347  return *this;
348 }
349 
350 void
352 {
353  _backgroundColor = color;
354 }
355 
356 void
357 Board::drawDot( double x, double y, int depthValue )
358 {
359  if ( depthValue != -1 )
360  _shapes.push_back( new Dot( _state.unit(x), _state.unit(y),
361  _state.penColor, _state.lineWidth, depthValue ) );
362  else
363  _shapes.push_back( new Dot( _state.unit(x), _state.unit(y),
365 }
366 
367 void
368 Board::drawLine( double x1, double y1, double x2, double y2,
369  int depthValue /* = -1 */ )
370 {
371  if ( depthValue != -1 )
372  _shapes.push_back( new Line( _state.unit(x1), _state.unit(y1),
373  _state.unit(x2), _state.unit(y2),
375  _state.lineStyle, _state.lineCap, _state.lineJoin, depthValue ) );
376  else
377  _shapes.push_back( new Line( _state.unit(x1), _state.unit(y1),
378  _state.unit(x2), _state.unit(y2),
381 }
382 
383 void
384 Board::drawQuadraticBezierCurve( double x1, double y1, double x2, double y2, double x3, double y3,
385  int depthValue /* = -1 */ )
386 {
387  if ( depthValue != -1 )
388  _shapes.push_back( new QuadraticBezierCurve( _state.unit(x1), _state.unit(y1),
389  _state.unit(x2), _state.unit(y2), _state.unit(x3), _state.unit(y3),
391  _state.lineStyle, _state.lineCap, _state.lineJoin, depthValue ) );
392  else
393  _shapes.push_back( new QuadraticBezierCurve( _state.unit(x1), _state.unit(y1),
394  _state.unit(x2), _state.unit(y2), _state.unit(x3), _state.unit(y3),
397 }
398 
399 void
400 Board::drawArrow( double x1, double y1, double x2, double y2,
401  bool filledArrow /* = false */,
402  int depthValue /* = -1 */ )
403 {
404  if ( depthValue != -1 )
405  _shapes.push_back( new Arrow( _state.unit(x1), _state.unit(y1),
406  _state.unit(x2), _state.unit(y2),
409  else
410  _shapes.push_back( new Arrow( _state.unit(x1), _state.unit(y1),
411  _state.unit(x2), _state.unit(y2),
414 }
415 
416 void
417 Board::drawRectangle( double x, double y,
418  double width, double height,
419  int depthValue /* = -1 */ )
420 {
421  int d = (depthValue != -1) ? depthValue : _nextDepth--;
422  _shapes.push_back( new Rectangle( _state.unit(x), _state.unit(y), _state.unit(width), _state.unit(height),
425 }
426 
427 void
428 Board::drawImage(std::string filename, double x, double y,
429  double width, double height,
430  int depthValue, double alpha /* = -1 */ )
431 {
432  int d = (depthValue != -1) ? depthValue : _nextDepth--;
433  _shapes.push_back( new Image( _state.unit(x), _state.unit(y), _state.unit(width), _state.unit(height),
434  filename, d, alpha ) );
435 }
436 
437 
438 void
439 Board::fillRectangle( double x, double y,
440  double width, double height,
441  int depthValue /* = -1 */ )
442 {
443  int d = (depthValue != -1) ? depthValue : _nextDepth--;
444  _shapes.push_back( new Rectangle( _state.unit(x), _state.unit(y), _state.unit(width), _state.unit(height),
447  d ) );
448 }
449 
450 void
451 Board::drawCircle( double x, double y, double radius,
452  int depthValue /* = -1 */ )
453 {
454  int d = (depthValue != -1) ? depthValue : _nextDepth--;
455  _shapes.push_back( new Circle( _state.unit(x), _state.unit(y), _state.unit(radius),
458 }
459 
460 void
461 Board::drawArc(double x, double y, double radius, double angle1, double angle2,
462  bool neg, int depthValue /*= -1*/ ){
463  int d = (depthValue != -1) ? depthValue : _nextDepth--;
464  _shapes.push_back( new Arc( _state.unit(x), _state.unit(y), _state.unit(radius),
465  angle1, angle2, neg,_state.penColor,
467 }
468 
469 
470 void
471 Board::fillCircle( double x, double y,
472  double radius,
473  int depthValue /* = -1 */ )
474 {
475  int d = (depthValue != -1) ? depthValue : _nextDepth--;
476  _shapes.push_back( new Circle( _state.unit(x), _state.unit(y), _state.unit(radius),
478  0.0f, _state.lineStyle, d ) );
479 }
480 
481 void
482 Board::drawEllipse( double x, double y,
483  double xRadius, double yRadius,
484  int depthValue /* = -1 */ )
485 {
486  int d = (depthValue != -1) ? depthValue : _nextDepth--;
487  _shapes.push_back( new Ellipse( _state.unit(x), _state.unit(y),
488  _state.unit(xRadius), _state.unit(yRadius),
493  d ) );
494 }
495 
496 void
497 Board::fillEllipse( double x, double y,
498  double xRadius, double yRadius,
499  int depthValue /* = -1 */ )
500 {
501  int d = depthValue ? depthValue : _nextDepth--;
502  _shapes.push_back( new Ellipse( _state.unit(x), _state.unit(y), _state.unit(xRadius), _state.unit(yRadius),
505  0.0f,
507  d ) );
508 }
509 
510 void
511 Board::drawPolyline( const std::vector<Point> & points,
512  int depthValue /* = -1 */ )
513 {
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 ) {
519  (*it) = _state.unit( *it );
520  ++it;
521  }
522  _shapes.push_back( new Polyline( v, false, _state.penColor, _state.fillColor,
525  _state.lineCap,
527  d ) );
528 }
529 
530 void
531 Board::drawClosedPolyline( const std::vector<Point> & points,
532  int depthValue /* = -1 */ )
533 {
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 ) {
539  (*it) = _state.unit( *it );
540  ++it;
541  }
542  _shapes.push_back( new Polyline( v, true, _state.penColor, _state.fillColor,
545  _state.lineCap,
547  d ) );
548 }
549 
550 void
551 Board::fillPolyline( const std::vector<Point> & points,
552  int depthValue /* = -1 */ )
553 {
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 ) {
559  (*it) = _state.unit( *it );
560  ++it;
561  }
562  _shapes.push_back( new Polyline( v, true, DGtal::Color::None, _state.penColor,
563  0.0f,
565  _state.lineCap,
567  d ) );
568 }
569 
570 void
571 Board::drawTriangle( double x1, double y1,
572  double x2, double y2,
573  double x3, double y3,
574  int depthValue /* = -1 */ )
575 {
576  int d = (depthValue != -1) ? depthValue : _nextDepth--;
577  std::vector<Point> points;
578  points.push_back( Point( _state.unit(x1), _state.unit(y1) ) );
579  points.push_back( Point( _state.unit(x2), _state.unit(y2) ) );
580  points.push_back( Point( _state.unit(x3), _state.unit(y3) ) );
581  _shapes.push_back( new Polyline( points, true, _state.penColor, _state.fillColor,
584  _state.lineCap,
586  d ) );
587 }
588 
589 void
591  const Point & p2,
592  const Point & p3,
593  int depthValue /* = -1 */ )
594 {
595  int d = (depthValue != -1) ? depthValue : _nextDepth--;
596  std::vector<Point> points;
597  points.push_back( Point( _state.unit(p1.x), _state.unit(p1.y) ) );
598  points.push_back( Point( _state.unit(p2.x), _state.unit(p2.y) ) );
599  points.push_back( Point( _state.unit(p3.x), _state.unit(p3.y) ) );
600  _shapes.push_back( new Polyline( points, true, _state.penColor, _state.fillColor,
603  _state.lineCap,
605  d ) );
606 }
607 
608 void
609 Board::fillTriangle( double x1, double y1,
610  double x2, double y2,
611  double x3, double y3,
612  int depthValue /* = -1 */ )
613 {
614  int d = (depthValue != -1) ? depthValue : _nextDepth--;
615  std::vector<Point> points;
616  points.push_back( Point( _state.unit(x1), _state.unit(y1) ) );
617  points.push_back( Point( _state.unit(x2), _state.unit(y2) ) );
618  points.push_back( Point( _state.unit(x3), _state.unit(y3) ) );
619  _shapes.push_back( new Polyline( points, true, DGtal::Color::None, _state.penColor,
620  0.0f,
622  _state.lineCap,
624  d ) );
625 }
626 
627 void
629  const Point & p2,
630  const Point & p3,
631  int depthValue /* = -1 */ )
632 {
633  int d = (depthValue != -1) ? depthValue : _nextDepth--;
634  std::vector<Point> points;
635  points.push_back( Point( _state.unit(p1.x), _state.unit(p1.y) ) );
636  points.push_back( Point( _state.unit(p2.x), _state.unit(p2.y) ) );
637  points.push_back( Point( _state.unit(p3.x), _state.unit(p3.y) ) );
638  _shapes.push_back( new Polyline( points, true, DGtal::Color::None, _state.penColor,
639  0.0f,
641  _state.lineCap,
643  d ) );
644 }
645 
646 void
648  const DGtal::Color & color1,
649  const Point & p2,
650  const DGtal::Color & color2,
651  const Point & p3,
652  const DGtal::Color & color3,
653  unsigned char divisions,
654  int depthValue /* = -1 */ )
655 {
656  int d = (depthValue != -1) ? depthValue : _nextDepth--;
657  _shapes.push_back( new GouraudTriangle( Point( _state.unit(p1.x), _state.unit(p1.y) ), color1,
658  Point( _state.unit(p2.x), _state.unit(p2.y) ), color2,
659  Point( _state.unit(p3.x), _state.unit(p3.y) ), color3,
660  divisions, d ) );
661 }
662 
663 void
665  const float brightness1,
666  const Point & p2,
667  const float brightness2,
668  const Point & p3,
669  const float brightness3,
670  unsigned char divisions,
671  int depthValue /* = -1 */ )
672 {
673  DGtal::Color color1( _state.penColor );
674  DGtal::Color color2( _state.penColor );
675  DGtal::Color color3( _state.penColor );
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 ) ) );
685  fillGouraudTriangle( Point( _state.unit(p1.x), _state.unit(p1.y) ), color1,
686  Point( _state.unit(p2.x), _state.unit(p2.y) ), color2,
687  Point( _state.unit(p3.x), _state.unit(p3.y) ), color3,
688  divisions,
689  depthValue );
690 }
691 
692 void
693 Board::drawText( double x, double y, const char * text,
694  int depthValue /* = -1 */ )
695 {
696  int d = (depthValue != -1) ? depthValue : _nextDepth--;
697  _shapes.push_back( new Text( _state.unit(x), _state.unit(y), text,
699 }
700 
701 void
702 Board::drawText( double x, double y, const std::string & str, int depthValue /* = -1 */ )
703 {
704  int d = (depthValue != -1) ? depthValue : _nextDepth--;
705  _shapes.push_back( new Text( _state.unit(x), _state.unit(y), str,
707 }
708 
709 void
710 Board::drawBoundingBox( int depthValue /* = -1 */ )
711 {
712  int d = (depthValue != -1) ? depthValue : _nextDepth--;
713  Rect box = boundingBox();
714  _shapes.push_back( new Rectangle( _state.unit(box.left),
715  _state.unit(box.top),
716  _state.unit(box.width),
717  _state.unit(box.height),
722  _state.lineCap,
724  d ) );
725 }
726 
727 void
728 Board::setClippingRectangle( double xLeft, double yTop,
729  double rectWidth, double rectHeight )
730 {
732  _clippingPath << _state.unit( Point( xLeft, yTop ) );
733  _clippingPath << _state.unit( Point( xLeft + rectWidth, yTop ) );
734  _clippingPath << _state.unit( Point( xLeft + rectWidth, yTop - rectHeight) );
735  _clippingPath << _state.unit( Point( xLeft , yTop - rectHeight ) );
736 }
737 
738 void
739 Board::setClippingPath( const std::vector<Point> & points )
740 {
742  std::vector<Point>::const_iterator it = points.begin();
743  std::vector<Point>::const_iterator end = points.end();
744  while ( it != end ) {
745  _clippingPath << _state.unit( *it );
746  ++it;
747  }
748 }
749 
750 void
752 {
753  _clippingPath = path;
754  _clippingPath.setClosed( true );
755  if ( _clippingPath.size() > 1 ) {
756  if ( _clippingPath[0] == _clippingPath[ _clippingPath.size() - 1 ] )
758  }
759  unsigned int n = _clippingPath.size();
760  for ( unsigned int i = 0; i < n; ++i ) {
762  }
763 }
764 
765 
766 void
768  unsigned int times,
769  double dx, double dy, double scaleValue )
770 {
771  Shape * s = shape.clone();
772  while ( times-- ) {
773  (*this) << (*s);
774  if ( scaleValue != 1.0 )
775  s->scale( scaleValue );
776  s->translate( dx, dy );
777  }
778  delete s;
779 }
780 
781 void
783  unsigned int times,
784  double dx, double dy,
785  double scaleX, double scaleY,
786  double angle )
787 {
788  Shape * s = shape.clone();
789  while ( times-- ) {
790  (*this) << (*s);
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 );
794  }
795  delete s;
796 }
797 
798 void
799 Board::saveEPS( std::ostream &out, PageSize size, double margin ) const
800 {
801  saveEPS( out, pageSizes[size][0], pageSizes[size][1], margin );
802 }
803 
804 void
805 Board::saveEPS( const char * filename, PageSize size, double margin ) const
806 {
807  saveEPS( filename, pageSizes[size][0], pageSizes[size][1], margin );
808 }
809 
810 
811 void
812 Board::saveEPS( const char * filename, double pageWidth, double pageHeight, double margin ) const
813 {
814  std::ofstream file( filename );
815  saveEPS(file, pageWidth, pageHeight, margin);
816  file.close();
817 }
818 
819 void
820 Board::saveEPS( std::ostream &out, double pageWidth, double pageHeight, double margin ) const
821 {
822  Rect box = boundingBox();
823  bool clipping = _clippingPath.size() > 2;
824  if ( clipping )
825  box = box && _clippingPath.boundingBox();
826 
827  TransformEPS transform;
828  transform.setBoundingBox( box, pageWidth, pageHeight, margin );
829 
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;
833  {
834  time_t t = time(0);
835  char str_time[255];
836  secured_ctime( str_time, &t, 255 );
837  out << "%%CreationDate: " << str_time;
838  }
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;
844 
845  out << "%Magnification: 1.0000" << std::endl;
846  out << "%%EndComments" << std::endl;
847 
848  out << 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;
875 
876  if ( clipping ) {
877  out << " newpath ";
878  _clippingPath.flushPostscript( out, transform );
879  out << " 0 slw clip " << std::endl;
880  }
881 
882  // Draw the background color if needed.
885  r.flushPostscript( out, transform );
886  }
887 
888  // Draw the shapes
889  std::vector< Shape* > shapes = _shapes;
890 
891  stable_sort( shapes.begin(), shapes.end(), shapeGreaterDepth );
892  std::vector< Shape* >::const_iterator i = shapes.begin();
893  std::vector< Shape* >::const_iterator end = shapes.end();
894 
895  while ( i != end ) {
896  (*i)->flushPostscript( out, transform );
897  ++i;
898  }
899  out << "showpage" << std::endl;
900  out << "%%Trailer" << std::endl;
901  out << "%EOF" << std::endl;
902 }
903 
904 
905 
906 void
907 Board::saveFIG( const char * filename, PageSize size, double margin, bool includeFIGHeader ) const
908 {
909  saveFIG( filename, pageSizes[size][0], pageSizes[size][1], margin, includeFIGHeader );
910 }
911 void
912 Board::saveFIG( std::ostream &out, PageSize size, double margin, bool includeFIGHeader ) const
913 {
914  saveFIG( out, pageSizes[size][0], pageSizes[size][1], margin, includeFIGHeader );
915 }
916 void
917 Board::saveFIG( const char * filename, double pageWidth, double pageHeight, double margin,
918  bool includeFIGHeader ) const
919 {
920  std::ofstream file( filename );
921  saveFIG( file, pageWidth, pageHeight, margin, includeFIGHeader);
922  file.close();
923 }
924 
925 void
926 Board::saveFIG( std::ostream &file, double pageWidth, double pageHeight, double margin, bool includeFIGHeader ) const
927 {
928 
929 
930  TransformFIG transform;
931  Rect box = boundingBox();
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";
937  file << "Center\n";
938  file << "Metric\n";
939  file << "A4\n";
940  file << "100.00\n";
941  file << "Single\n";
942  file << "-2\n";
943  file << "1200 2\n";
944  }else{
945  file << "\n";
946  }
947  std::map<DGtal::Color,int> colormap;
948  int maxColor = 32;
949 
950 
951  colormap[DGtal::Color(0,0,0)] = 0;
952  colormap[DGtal::Color(0,0,255)] = 1;
953  colormap[DGtal::Color(0,255,0)] = 2;
954  colormap[DGtal::Color(0,255,255)] = 0;
955  colormap[DGtal::Color(255,0,0)] = 4;
956  colormap[DGtal::Color(255,0,255)] = 0;
957  colormap[DGtal::Color(255,255,0)] = 6;
958  colormap[DGtal::Color(255,255,255)] = 7;
959 
960 
961  std::vector< Shape* > shapes = _shapes;
962  stable_sort( shapes.begin(), shapes.end(), shapeGreaterDepth );
963  std::vector< Shape* >::const_iterator i = shapes.begin();
964  std::vector< Shape* >::const_iterator end = shapes.end();
965  while ( i != 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++;
972  ++i;
973  }
974 
975  if ( colormap.find( _backgroundColor ) == colormap.end()
976  && _backgroundColor.valid() )
977  colormap[ _backgroundColor ] = maxColor++;
978 
979  // Write the colormap
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",
986  iColormap->second,
987  iColormap->first.red(),
988  iColormap->first.green(),
989  iColormap->first.blue() );
990  if ( iColormap->second >= 32 ) file << colorString;
991  ++iColormap;
992  }
993 
994  // Draw the background color if needed.
997  r.depth( std::numeric_limits<int>::max() );
998  r.flushFIG( file, transform, colormap );
999  }
1000 
1001  // Draw the shapes.
1002  i = shapes.begin();
1003  while ( i != end ) {
1004  // notice << (*i)->name() << " " << (*i)->depth() << '\n';
1005  (*i)->flushFIG( file, transform, colormap );
1006  ++i;
1007  }
1008 }
1009 
1010 
1011 void
1012 Board::saveSVG( const char * filename, PageSize size, double margin ) const
1013 {
1014  saveSVG( filename, pageSizes[size][0], pageSizes[size][1], margin );
1015 }
1016 
1017 void
1018 Board::saveSVG( std::ostream &out, PageSize size, double margin ) const
1019 {
1020  saveSVG( out, pageSizes[size][0], pageSizes[size][1], margin );
1021 }
1022 
1023 
1024 void
1025 Board::saveSVG( const char * filename, double pageWidth, double pageHeight, double margin ) const
1026 {
1027  std::ofstream file( filename );
1028  saveSVG(file, pageWidth, pageHeight, margin);
1029  file.close();
1030 }
1031 
1032 
1033 
1034 void
1035 Board::saveSVG( std::ostream &file, double pageWidth, double pageHeight, double margin, std::string filename ) const
1036 {
1037 
1038  TransformSVG transform;
1039  Rect box = boundingBox();
1040  bool clipping = _clippingPath.size() > 2;
1041  if ( clipping )
1042  box = box && _clippingPath.boundingBox();
1043  transform.setBoundingBox( box, pageWidth, pageHeight, margin );
1044 
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;
1048 
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;
1057  } else {
1058  file << "<svg width=\""
1059  << ( box.width / ppmm ) << "mm"
1060  << "\" height=\""
1061  << ( box.height / ppmm ) << "mm"
1062  << "\" " << std::endl;
1063  file << " viewBox=\"0 0 "
1064  << box.width << " "
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;
1067 
1068  }
1069 
1070  file << "<desc>" << filename
1071  << ", created with the Board library (Copyleft) 2007 Sebastien Fourey"
1072  << "</desc>" << std::endl;
1073 
1074  if ( clipping ) {
1075  file << "<g clip-rule=\"nonzero\">\n"
1076  << " <clipPath id=\"GlobalClipPath\">\n"
1077  << " <path clip-rule=\"evenodd\" d=\"";
1078  _clippingPath.flushSVGCommands( file, transform );
1079  file << "\" />\n";
1080  file << " </clipPath>\n";
1081  file << "<g clip-path=\"url(#GlobalClipPath)\">\n";
1082  }
1083 
1084  // Draw the background color if needed.
1087  r.flushSVG( file, transform );
1088  }
1089 
1090  // Draw the shapes.
1091  std::vector< Shape* > shapes = _shapes;
1092  stable_sort( shapes.begin(), shapes.end(), shapeGreaterDepth );
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 );
1097  ++i;
1098  }
1099 
1100  if ( clipping )
1101  file << "</g>\n</g>";
1102  file << "</svg>" << std::endl;
1103 
1104 }
1105 
1106 
1107 void
1108 Board::save( const char * filename, double pageWidth, double pageHeight, double margin ) const
1109 {
1110  const char * extension = filename + strlen( filename );
1111  while ( extension > filename && *extension != '.' )
1112  --extension;
1113  if ( !(strcmp( extension, ".eps" )) || !(strcmp( extension, ".EPS" )) ) {
1114  saveEPS( filename, pageWidth, pageHeight, margin );
1115  return;
1116  }
1117  if ( !(strcmp( extension, ".fig" )) || !(strcmp( extension, ".FIG" )) ) {
1118  saveFIG( filename, pageWidth, pageHeight, margin );
1119  return;
1120  }
1121  if ( !(strcmp( extension, ".svg" )) || !(strcmp( extension, ".SVG" )) ) {
1122  saveSVG( filename, pageWidth, pageHeight, margin );
1123  return;
1124  }
1125  if ( !(strcmp( extension, ".tikz" )) || !(strcmp( extension, ".TIKZ" )) ) {
1126  saveTikZ( filename, pageWidth, pageHeight, margin );
1127  return;
1128  }
1129 }
1130 
1131 void
1132 Board::save( const char * filename, PageSize size, double margin ) const
1133 {
1134  save( filename, pageSizes[size][0], pageSizes[size][1], margin );
1135 }
1136 
1137 #ifdef WITH_CAIRO
1138 void
1139 Board::saveCairo( const char * filename, CairoType type, PageSize size, double margin ) const
1140 {
1141  saveCairo( filename, type, pageSizes[size][0], pageSizes[size][1], margin );
1142 }
1143 void
1144 Board::saveCairo( const char * filename, CairoType type, double pageWidth, double pageHeight, double margin ) const
1145 {
1146  cairo_surface_t *surface;
1147  cairo_t *cr;
1148 
1149  double cairoWidth, cairoHeight;
1150 
1151  TransformCairo transform;
1152  Rect box = boundingBox();
1153 
1154  bool clipping = _clippingPath.size() > 2;
1155  if ( clipping )
1156  box = box && _clippingPath.boundingBox();
1157  transform.setBoundingBox( box, pageWidth, pageHeight, margin );
1158 
1159  if ( pageWidth > 0 && pageHeight > 0 )
1160  {
1161  cairoWidth = pageWidth;
1162  cairoHeight = pageHeight;
1163  }
1164  else
1165  {
1166  cairoWidth = box.width;
1167  cairoHeight = box.height;
1168  }
1169 
1170  switch (type)
1171  {
1172  case CairoPDF:
1173  surface = cairo_pdf_surface_create (filename, cairoWidth, cairoHeight); break;
1174  case CairoPS:
1175  surface = cairo_ps_surface_create (filename, cairoWidth, cairoHeight); break;
1176  case CairoEPS:
1177  surface = cairo_ps_surface_create (filename, cairoWidth, cairoHeight);
1178  cairo_ps_surface_set_eps(surface, true); break;
1179  case CairoSVG:
1180  surface = cairo_svg_surface_create (filename, cairoWidth, cairoHeight); break;
1181  case CairoPNG:
1182  default:
1183  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, (int)cairoWidth, (int)cairoHeight);
1184  }
1185 
1186  cr = cairo_create (surface);
1187 
1188  /* For 1.0 x 1.0 coordinate space */
1189  //cairo_scale (cr, cairoWidth, cairoHeight);
1190 
1191  //temp: http://zetcode.com/tutorials/cairographicstutorial/basicdrawing/
1192  //temp: http://www.graphviz.org/pub/scm/graphviz-cairo/plugin/cairo/gvrender_cairo.c
1193 
1194  // Draw the background color if needed.
1197  r.flushCairo( cr, transform );
1198  }
1199 
1200  // Draw the shapes.
1201  std::vector< Shape* > shapes = _shapes;
1202  stable_sort( shapes.begin(), shapes.end(), shapeGreaterDepth );
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 );
1207  ++i;
1208  }
1209 
1210  if (type==CairoPNG)
1211  cairo_surface_write_to_png (surface, filename);
1212 
1213  cairo_destroy (cr);
1214  cairo_surface_destroy (surface);
1215 }
1216 #endif
1217 
1218 void
1219 Board::saveTikZ( const char * filename, PageSize size, double margin ) const
1220 {
1221  saveTikZ( filename, pageSizes[size][0], pageSizes[size][1], margin );
1222 }
1223 
1224 void
1225 Board::saveTikZ( std::ostream & out, PageSize size, double margin ) const
1226 {
1227  saveTikZ( out, pageSizes[size][0], pageSizes[size][1], margin );
1228 }
1229 
1230 void
1231 Board::saveTikZ( const char * filename, double /*pageWidth*/, double pageHeight, double margin ) const
1232 {
1233  std::ofstream file( filename );
1234  saveTikZ(file, pageHeight, pageHeight, margin);
1235  file.close();
1236 }
1237 
1238 void
1239 Board::saveTikZ( std::ostream &out, double pageWidth, double pageHeight, double margin ) const
1240 {
1241  TransformTikZ transform;
1242  Rect box = boundingBox();
1243  bool clipping = _clippingPath.size() > 2;
1244  if ( clipping )
1245  box = box && _clippingPath.boundingBox();
1246  transform.setBoundingBox( box, pageWidth, pageHeight, margin );
1247 
1248  out << "\\begin{tikzpicture}[anchor=south west,text depth=0,x={(1pt,0pt)},y={(0pt,-1pt)}]" << std::endl;
1249 
1250  if ( clipping ) {
1251  out << "\\clip ";
1252  _clippingPath.flushSVGCommands( out, transform );
1253  out << "\n";
1254  }
1255 
1256  // Draw the background color if needed.
1259  r.flushTikZ( out, transform );
1260  }
1261 
1262  // Draw the shapes.
1263  std::vector< Shape* > shapes = _shapes;
1264  stable_sort( shapes.begin(), shapes.end(), shapeGreaterDepth );
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 );
1269  ++i;
1270  }
1271 
1272  //if ( clipping )
1273  // out << "</g>\n</g>";
1274  out << "\\end{tikzpicture}" << std::endl;
1275 }
1276 
1277 
1278 } // namespace LibBoard;
1279 
1280 
Structure representing an RGB triple with alpha component.
Definition: Color.h:67
Color & setRGBi(const unsigned char aRedValue, const unsigned char aGreenValue, const unsigned char aBlueValue, const unsigned char aAlphaValue=255)
bool valid() const
static const Color None
Definition: Color.h:388
void green(const unsigned char aGreenValue)
void red(const unsigned char aRedValue)
static const Color Black
Definition: Color.h:389
Color & setRGBf(float red, float green, float blue, float alpha=1.0)
Definition: Color.cpp:65
void blue(const unsigned char aBlueValue)
Class for EPS, FIG or SVG drawings.
Definition: Board.h:35
void drawRectangle(double x, double y, double width, double height, int depthValue=-1)
Definition: Board.cpp:417
Board & setFont(const Fonts::Font font, double fontSize)
Definition: Board.cpp:336
Board & setPenColor(const DGtal::Color &color)
Definition: Board.cpp:298
void fillTriangle(double x1, double y1, double x2, double y2, double x3, double y3, int depthValue=-1)
Definition: Board.cpp:609
void setClippingRectangle(double x, double y, double width, double height)
Definition: Board.cpp:728
DGtal::Color _backgroundColor
Definition: Board.h:956
void drawEllipse(double x, double y, double xRadius, double yRadius, int depthValue=-1)
Definition: Board.cpp:482
State _state
Definition: Board.h:955
void drawPolyline(const std::vector< Point > &points, int depthValue=-1)
Definition: Board.cpp:511
Board & setFontSize(double fontSize)
Definition: Board.cpp:344
void saveTikZ(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
Definition: Board.cpp:1219
void saveFIG(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0, bool includeFIGHeader=true) const
Definition: Board.cpp:907
void setClippingPath(const std::vector< Point > &points)
Definition: Board.cpp:739
Board & operator<<(const Shape &shape)
Definition: Board.cpp:133
void drawTriangle(double x1, double y1, double x2, double y2, double x3, double y3, int depthValue=-1)
Definition: Board.cpp:571
void drawQuadraticBezierCurve(double x1, double y1, double x2, double y2, double x3, double y3, int depthValue=-1)
Definition: Board.cpp:384
void fillCircle(double x, double y, double radius, int depthValue=-1)
Definition: Board.cpp:471
void drawLine(double x1, double y1, double x2, double y2, int depthValue=-1)
Definition: Board.cpp:368
void fillPolyline(const std::vector< Point > &points, int depthValue=-1)
Definition: Board.cpp:551
Board & operator=(const Board &other)
Definition: Board.cpp:117
void save(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
Definition: Board.cpp:1132
Board & setPenColorRGBi(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha=255)
Definition: Board.cpp:278
void drawDot(double x, double y, int depthValue=-1)
Definition: Board.cpp:357
static const double Degree
Definition: Board.h:44
void drawClosedPolyline(const std::vector< Point > &points, int depthValue=-1)
Definition: Board.cpp:531
void drawArc(double x, double y, double radius, double angle1, double angle2, bool neg, int depthValue=-1)
Definition: Board.cpp:461
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)
Definition: Board.cpp:647
void drawArrow(double x1, double y1, double x2, double y2, bool filled=true, int depthValue=-1)
Definition: Board.cpp:400
Board & setPenColorRGBf(float red, float green, float blue, float alpha=1.0f)
Definition: Board.cpp:288
void drawCircle(double x, double y, double radius, int depthValue=-1)
Definition: Board.cpp:451
Shape & translate(double dx, double dy)
Definition: Board.cpp:176
void fillRectangle(double x, double y, double width, double height, int depthValue=-1)
Definition: Board.cpp:439
Board translated(double dx, double dy)
Definition: Board.cpp:221
Shape & rotate(double angle, const Point &center)
Definition: Board.cpp:160
void addDuplicates(const Shape &shape, unsigned int times, double dx, double dy, double scale=1.0)
Definition: Board.cpp:767
Board scaled(double sx, double sy)
Definition: Board.cpp:227
void drawText(double x, double y, const char *text, int depthValue=-1)
Definition: Board.cpp:693
Board & setFillColorRGBi(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha=255)
Definition: Board.cpp:305
Board & setFillColor(const DGtal::Color &color)
Definition: Board.cpp:322
Board & setLineWidth(double width)
Definition: Board.cpp:329
void fillEllipse(double x, double y, double xRadius, double yRadius, int depthValue=-1)
Definition: Board.cpp:497
void saveEPS(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
Definition: Board.cpp:805
void backgroundColor(const DGtal::Color &color)
Definition: Board.cpp:351
void drawImage(std::string filename, double x, double y, double width, double height, int depthValue=-1, double alpha=1.0)
Definition: Board.cpp:428
void saveSVG(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
Definition: Board.cpp:1012
Board & setFillColorRGBf(float red, float green, float blue, float alpha=1.0f)
Definition: Board.cpp:315
Board(const DGtal::Color &backgroundColor=DGtal::Color::None)
Definition: Board.cpp:104
void setUnit(Unit unit)
Definition: Board.cpp:240
Path _clippingPath
Definition: Board.h:957
Shape & scale(double sx, double sy)
Definition: Board.cpp:184
Board rotated(double angle, const Point &center)
Definition: Board.cpp:209
void drawBoundingBox(int depthValue=-1)
Definition: Board.cpp:710
void saveCairo(const char *filename, CairoType type=CairoPNG, PageSize size=Board::BoundingBox, double margin=10.0) const
Definition: Board.cpp:1139
bool shapeGreaterDepth(const Shape *s1, const Shape *s2)
Definition: Shapes.cpp:95
void secured_ctime(char *str, const time_t *t, size_t count)
A line between two points with an arrow at one extremity.
Definition: Board/Shapes.h:665
double unit(const double &x)
Definition: Board.h:951
DGtal::Color penColor
Definition: Board.h:941
Shape::LineJoin lineJoin
Definition: Board.h:946
Shape::LineCap lineCap
Definition: Board.h:945
Fonts::Font font
Definition: Board.h:947
Shape::LineStyle lineStyle
Definition: Board.h:944
DGtal::Color fillColor
Definition: Board.h:942
A line between two points.
Definition: Board/Shapes.h:398
A triangle with shaded filling according to colors given for each vertex.
A line between two points.
Definition: Board/Shapes.h:534
A path, according to Postscript and SVG definition.
Definition: Path.h:43
unsigned int size() const
Definition: Path.h:249
void clear()
Definition: Path.h:231
Path & pop_back()
Definition: Path.cpp:22
Path & scale(double sx, double sy)
Definition: Path.cpp:108
Point center() const
Definition: Path.cpp:36
void setClosed(bool closed)
Definition: Path.h:255
Rect boundingBox() const
Definition: Path.cpp:272
Path & translate(double dx, double dy)
Definition: Path.cpp:81
void flushPostscript(std::ostream &stream, const TransformEPS &transform) const
Definition: Path.cpp:154
void flushSVGCommands(std::ostream &stream, const TransformSVG &transform) const
Definition: Path.cpp:193
Path & rotate(double angle, const Point &center)
Definition: Path.cpp:43
Struct representing a 2D point.
Definition: Point.h:27
double y
Definition: Point.h:30
double x
Definition: Point.h:29
A polygonal line described by a series of 2D points.
Definition: Board/Shapes.h:765
A quadratic Bezier curve having 3 control points. NB. It is also a parabola arc.
Struct representing a rectangle on the plane.
Definition: Rect.h:26
double height
Definition: Rect.h:31
double width
Definition: Rect.h:30
double left
Definition: Rect.h:28
double top
Definition: Rect.h:29
A group of shapes.
Definition: ShapeList.h:28
void addShape(const Shape &shape, double scaleFactor)
Definition: ShapeList.cpp:122
Shape & rotate(double angle, const Point &center)
Definition: ShapeList.cpp:205
std::vector< Shape * > _shapes
Definition: ShapeList.h:169
Shape & translate(double dx, double dy)
Definition: ShapeList.cpp:236
Shape & scale(double sx, double sy)
Definition: ShapeList.cpp:254
Point center() const
Definition: ShapeList.cpp:192
Rect boundingBox() const
Definition: ShapeList.cpp:379
ShapeList & clear()
Definition: ShapeList.cpp:43
Abstract structure for a 2D shape.
Definition: Board/Shapes.h:58
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 &center)=0
A piece of text.
Structure representing a scaling and translation suitable for an Cairo output.
Definition: Transforms.h:112
Structure representing a scaling and translation suitable for an EPS output.
Definition: Transforms.h:59
void setBoundingBox(const Rect &rect, const double pageWidth, const double pageHeight, const double margin)
Definition: Transforms.cpp:68
Structure representing a scaling and translation suitable for an XFig output.
Definition: Transforms.h:73
Structure representing a scaling and translation suitable for an SVG output.
Definition: Transforms.h:95
Structure representing a scaling and translation suitable for an TikZ output.
Definition: Transforms.h:129
int max(int a, int b)
MyPointD Point
Definition: testClone2.cpp:383
Ellipse2D< Space > Ellipse
ImageContainerBySTLVector< Domain, Value > Image