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