14 #include "Board/ShapeList.h"
15 #include "Board/Tools.h"
47 _nextDepth = std::numeric_limits<int>::max() - 1;
54 std::vector<Shape*>::const_iterator i =
_shapes.begin();
55 std::vector<Shape*>::const_iterator end =
_shapes.end();
64 if ( ! other._shapes.size() )
return;
65 _shapes.resize( other._shapes.size(), 0 );
66 std::vector<Shape*>::iterator t = _shapes.begin();
67 std::vector<Shape*>::const_iterator i = other._shapes.begin();
68 std::vector<Shape*>::const_iterator end = other._shapes.end();
77 ShapeList::operator=(
const ShapeList & other )
80 if ( ! other._shapes.size() )
return *
this;
81 _shapes.resize( other._shapes.size(), 0 );
82 std::vector<Shape*>::iterator t = _shapes.begin();
83 std::vector<Shape*>::const_iterator i = other._shapes.begin();
84 std::vector<Shape*>::const_iterator end = other._shapes.end();
96 if (
typeid( shape ) ==
typeid( ShapeList ) ) {
98 const ShapeList & sl =
dynamic_cast<const ShapeList &
>( shape );
99 std::vector<Shape*> shapes = sl._shapes;
101 std::vector<Shape*>::iterator i = shapes.begin();
102 std::vector<Shape*>::iterator end = shapes.end();
104 Shape * s = (*i)->clone();
105 s->depth( _nextDepth-- );
106 _shapes.push_back( s );
110 Shape * s = shape.clone();
111 if ( s->depth() == -1 )
112 s->depth( _nextDepth-- );
113 _shapes.push_back( s );
114 if (
typeid( shape ) ==
typeid( Group ) ) {
115 _nextDepth =
dynamic_cast<const Group&
>(shape).minDepth() - 1;
122 ShapeList::addShape(
const Shape & shape,
double scaleFactor )
124 if (
typeid( shape ) ==
typeid( ShapeList ) ) {
126 const ShapeList & sl =
dynamic_cast<const ShapeList &
>( shape );
127 std::vector<Shape*> shapes = sl._shapes;
129 std::vector<Shape*>::iterator i = shapes.begin();
130 std::vector<Shape*>::iterator end = shapes.end();
132 Shape * s = (*i)->clone();
133 s->depth( _nextDepth-- );
134 if ( scaleFactor != 1.0 )
135 s->scaleAll( scaleFactor );
136 _shapes.push_back( s );
140 Shape * s = shape.clone();
141 if ( s->depth() == -1 )
142 s->depth( _nextDepth-- );
143 if ( scaleFactor != 1.0 )
144 s->scaleAll( scaleFactor );
145 _shapes.push_back( s );
146 if (
typeid( shape ) ==
typeid( Group ) ) {
147 _nextDepth =
dynamic_cast<const Group&
>(shape).minDepth() - 1;
153 ShapeList::dup(
unsigned int count )
155 if ( ! _shapes.size() ) {
156 warning <<
"dup() called with an empty list of shapes.\n";
160 (*this) << (*_shapes.back());
166 ShapeList::operator+=(
const Shape & shape )
168 if (
typeid( shape ) ==
typeid( ShapeList ) ) {
169 const ShapeList & sl =
dynamic_cast<const ShapeList &
>( shape );
170 std::vector<Shape*>::const_iterator i = sl._shapes.begin();
171 std::vector<Shape*>::const_iterator end = sl._shapes.end();
173 Shape * s = (*i)->clone();
174 _shapes.push_back( s );
178 _shapes.push_back( shape.clone() );
184 ShapeList::insert(
const Shape & ,
int )
186 warning <<
"ShapeList::insert() not implemented yet.\n";
192 ShapeList::center()
const {
193 std::vector<Shape*>::const_iterator i = _shapes.begin();
194 std::vector<Shape*>::const_iterator end = _shapes.end();
195 double f = 1.0 / _shapes.size();
198 r += f * (*i)->center();
205 ShapeList::rotate(
double angle,
const Point & rotCenter )
207 std::vector<Shape*>::iterator i = _shapes.begin();
208 std::vector<Shape*>::iterator end = _shapes.end();
210 (*i)->rotate( angle, rotCenter );
217 ShapeList::rotated(
double angle,
const Point & rotCenter )
219 ShapeList r( *
this );
220 return static_cast<ShapeList&
>( r.rotate( angle, rotCenter ) );
224 ShapeList::rotate(
double angle )
226 return ShapeList::rotate( angle, center() );
230 ShapeList::rotated(
double angle )
232 return static_cast<ShapeList&
>( ShapeList( *this ).rotate( angle, center() ) );
236 ShapeList::translate(
double dx,
double dy )
238 std::vector<Shape*>::iterator i = _shapes.begin();
239 std::vector<Shape*>::iterator end = _shapes.end();
241 (*i)->translate( dx, dy );
248 ShapeList::translated(
double dx,
double dy )
250 return static_cast<ShapeList&
>( ShapeList( *this ).translate( dx, dy ) );
254 ShapeList::scale(
double sx,
double sy )
258 std::vector<Shape*>::iterator i = _shapes.begin();
259 std::vector<Shape*>::iterator end = _shapes.end();
261 delta = (*i)->center() - c;
264 (*i)->scale( sx, sy );
265 delta = ( c + delta ) - (*i)->center();
266 (*i++)->translate( delta.
x, delta.
y );
272 ShapeList::scale(
double s )
274 return ShapeList::scale( s, s );
278 ShapeList::scaled(
double sx,
double sy )
280 return static_cast<ShapeList&
>( ShapeList( *this ).scale( sx, sy ) );
284 ShapeList::scaled(
double s )
286 return static_cast<ShapeList&
>( ShapeList( *this ).scale( s, s ) );
290 ShapeList::scaleAll(
double s )
292 std::vector<Shape*>::iterator i = _shapes.begin();
293 std::vector<Shape*>::iterator end = _shapes.end();
295 (*i++)->scaleAll( s );
300 ShapeList::flushPostscript( std::ostream & stream,
301 const TransformEPS & transform )
const
303 std::vector< Shape* > shapes = _shapes;
305 std::vector< Shape* >::const_iterator i = shapes.begin();
306 std::vector< Shape* >::const_iterator end = shapes.end();
307 stream <<
"%%% Begin ShapeList\n";
309 (*i++)->flushPostscript( stream, transform );
311 stream <<
"%%% End ShapeList\n";
315 ShapeList::flushFIG( std::ostream & stream,
316 const TransformFIG & transform,
317 std::map<DGtal::Color,int> & colormap )
const
319 std::vector< Shape* > shapes = _shapes;
321 std::vector< Shape* >::const_iterator i = shapes.begin();
322 std::vector< Shape* >::const_iterator end = shapes.end();
324 (*i)->flushFIG( stream, transform, colormap );
330 ShapeList::flushSVG( std::ostream & stream,
331 const TransformSVG & transform )
const
333 std::vector< Shape* > shapes = _shapes;
335 std::vector< Shape* >::const_iterator i = shapes.begin();
336 std::vector< Shape* >::const_iterator end = shapes.end();
339 (*i)->flushSVG( stream, transform );
347 ShapeList::flushCairo( cairo_t *cr,
348 const TransformCairo & transform )
const
350 std::vector< Shape* > shapes = _shapes;
352 std::vector< Shape* >::const_iterator i = shapes.begin();
353 std::vector< Shape* >::const_iterator end = shapes.end();
356 (*i)->flushCairo( cr, transform );
363 ShapeList::flushTikZ( std::ostream & stream,
364 const TransformTikZ & transform )
const
366 std::vector< Shape* > shapes = _shapes;
368 std::vector< Shape* >::const_iterator i = shapes.begin();
369 std::vector< Shape* >::const_iterator end = shapes.end();
370 stream <<
"\\begin{scope}\n";
372 (*i)->flushTikZ( stream, transform );
375 stream <<
"\\end{scope}\n";
379 ShapeList::boundingBox()
const
382 std::vector< Shape* >::const_iterator i = _shapes.begin();
383 std::vector< Shape* >::const_iterator end = _shapes.end();
384 if ( i == end )
return r;
385 r = (*i)->boundingBox();
388 r = r || (*i)->boundingBox();
395 ShapeList::minDepth()
const
397 int res = std::numeric_limits<int>::max();
400 std::vector< Shape* >::const_iterator i = _shapes.begin();
401 std::vector< Shape* >::const_iterator end = _shapes.end();
403 sl =
dynamic_cast<ShapeList*
>( *i );
409 if ( d < res ) res = d;
417 #define _HAS_MSVC_MIN_ true
421 ShapeList::maxDepth()
const
423 int res = std::numeric_limits<int>::min();
426 std::vector< Shape* >::const_iterator i = _shapes.begin();
427 std::vector< Shape* >::const_iterator end = _shapes.end();
429 sl =
dynamic_cast<ShapeList*
>( *i );
435 if ( d > res ) res = d;
441 #if defined( _HAS_MSVC_MIN_ )
442 #define min(A,B) ((A)<(B)?(A):(B))
446 ShapeList::shiftDepth(
int shift )
448 std::vector< Shape* >::const_iterator i = _shapes.begin();
449 std::vector< Shape* >::const_iterator end = _shapes.end();
451 (*i++)->shiftDepth( shift );
456 ShapeList::clone()
const
458 return new ShapeList( *
this );
462 ShapeList::last(
const unsigned int position )
464 return last<Shape>( position );
470 return last<Shape>( 0 );
478 const std::string Group::_name(
"GroupOfShapes");
487 Group::rotate(
double angle,
const Point & rotCenter )
489 ShapeList::rotate( angle, rotCenter );
490 _clippingPath.rotate( angle, rotCenter );
495 Group::rotate(
double angle )
497 ShapeList::rotate( angle );
498 _clippingPath.rotate( angle, center() );
503 Group::translate(
double dx,
double dy )
505 ShapeList::translate( dx, dy );
506 _clippingPath.translate( dx, dy );
511 Group::scale(
double sx,
double sy )
513 Point delta = _clippingPath.center() - center();
516 _clippingPath.scale( sx, sy );
517 ShapeList::scale( sx, sy );
518 delta = ( center() + delta ) - _clippingPath.center();
519 _clippingPath.translate( delta.
x, delta.
y );
524 Group::scale(
double s )
526 Point delta = _clippingPath.center() - center();
528 _clippingPath.scale( s );
529 ShapeList::scale( s );
530 delta = ( center() + delta ) - _clippingPath.center();
531 _clippingPath.translate( delta.
x, delta.
y );
536 Group::rotated(
double angle,
const Point & rotCenter )
538 return static_cast<const Group &
>( Group( *this ).rotate( angle, rotCenter ) );
542 Group::rotated(
double angle )
544 return static_cast<const Group &
>( Group( *this ).rotate( angle ) );
548 Group::translated(
double dx,
double dy )
550 return static_cast<const Group &
>( Group( *this ).translate( dx, dy ) );
554 Group::scaled(
double sx,
double sy )
556 return static_cast<const Group &
>( Group( *this ).scale( sx, sy ) );
560 Group::scaled(
double s )
562 return static_cast<const Group &
>( Group( *this ).scale( s ) );
567 Group::setClippingRectangle(
float x,
float y,
float width,
float height )
569 _clippingPath.clear();
570 _clippingPath <<
Point( x, y );
571 _clippingPath <<
Point( x + width, y );
572 _clippingPath <<
Point( x + width, y - height);
573 _clippingPath <<
Point( x , y - height );
577 Group::setClippingPath(
const std::vector<Point> & points )
579 _clippingPath.clear();
580 std::vector<Point>::const_iterator it = points.begin();
581 std::vector<Point>::const_iterator end = points.end();
582 while ( it != end ) {
583 _clippingPath << *it;
589 Group::setClippingPath(
const Path & path )
591 _clippingPath = path;
592 _clippingPath.setClosed(
true );
593 if ( _clippingPath.size() > 1 ) {
594 if ( _clippingPath[0] == _clippingPath[ _clippingPath.size() - 1 ] )
595 _clippingPath.pop_back();
600 Group::flushPostscript( std::ostream & stream,
601 const TransformEPS & transform )
const
603 if ( _clippingPath.size() > 2 ) {
604 stream <<
"%%% Begin Clipped Group " << _clippingCount <<
"\n";
605 stream <<
" gsave n ";
606 _clippingPath.flushPostscript( stream, transform );
607 stream <<
" 0 slw clip " << std::endl;
608 ShapeList::flushPostscript( stream, transform );
609 stream <<
" grestore\n";
610 stream <<
"%%% End Clipped Group " << _clippingCount <<
"\n";
613 stream <<
"%%% Begin Group\n";
614 ShapeList::flushPostscript( stream, transform );
615 stream <<
"%%% End Group\n";
620 Group::flushFIG( std::ostream & stream,
621 const TransformFIG & transform,
622 std::map<DGtal::Color,int> & colormap )
const
624 Rect box = boundingBox();
625 stream <<
"# Begin group\n";
627 << transform.mapX( box.left ) <<
" "
628 << transform.mapY( box.top ) <<
" "
629 << transform.mapX( box.left + box.width ) <<
" "
630 << transform.mapY( box.top - box.height ) <<
"\n";
631 ShapeList::flushFIG( stream, transform, colormap );
633 stream <<
"# End Group\n";
637 Group::flushSVG( std::ostream & stream,
638 const TransformSVG & transform )
const
640 if ( _clippingPath.size() > 2 ) {
641 stream <<
"<g clip-rule=\"nonzero\">\n"
642 <<
" <clipPath id=\"LocalClipPath" << _clippingCount <<
"\">\n"
643 <<
" <path clip-rule=\"evenodd\" d=\"";
644 _clippingPath.flushSVGCommands( stream, transform );
646 stream <<
" </clipPath>\n";
647 stream <<
"<g clip-path=\"url(#LocalClipPath" << _clippingCount <<
")\">\n";
649 ShapeList::flushSVG( stream, transform );
654 ShapeList::flushSVG( stream, transform );
661 Group::flushCairo( cairo_t * ,
662 const TransformCairo & )
const
670 Group::flushTikZ( std::ostream & stream,
671 const TransformTikZ & transform )
const
674 stream <<
"\\begin{scope}\n";
675 ShapeList::flushTikZ( stream, transform );
676 stream <<
"\\end{scope}\n";
680 Group::boundingBox()
const
682 if ( _clippingPath.size() > 2 )
683 return ShapeList::boundingBox() && _clippingPath.boundingBox();
685 return ShapeList::boundingBox();
692 return new Group( *
this );
696 Group::operator=(
const Group & other )
698 ShapeList::operator=( other );
702 unsigned int Group::_clippingCount = 0;