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;