Board  0.9.5
ShapeList.h
Go to the documentation of this file.
1 /* -*- mode: c++ -*- */
27 #ifndef BOARD_SHAPELIST_H
28 #define BOARD_SHAPELIST_H
29 
30 #include <queue>
31 #include <stack>
32 #include <typeinfo>
33 #include "board/Exception.h"
34 #include "board/Shape.h"
35 #include "board/Tools.h"
36 
37 namespace LibBoard
38 {
39 
40 struct Group;
41 
46 struct ShapeList : public Shape {
47 
48  typedef std::vector<Shape *>::size_type size_type;
49 
50  enum Direction
51  {
52  Top,
53  Right,
54  Bottom,
55  Left
56  };
57  enum Alignment
58  {
59  AlignTop,
60  AlignBottom,
61  AlignCenter,
62  AlignLeft,
63  AlignRight
64  };
65 
66  inline ShapeList();
67 
68  ShapeList(const ShapeList & other);
69 
70  ShapeList & operator=(const ShapeList & other);
71 
72  ShapeList(ShapeList && other);
73 
74  ShapeList & operator=(ShapeList && other);
75 
84  ShapeList(const Shape & shape, unsigned int times, double dx, double dy, double scale);
85 
96  ShapeList(const Shape & shape, unsigned int times, double dx, double dy, double scaleX, double scaleY, double angle);
97 
98  ~ShapeList() override;
99 
105  const std::string & name() const override;
106 
111  ShapeList & clear();
112 
113  ShapeList & rotate(double angle, const Point & center) override;
114 
121  ShapeList rotated(double angle, const Point & center);
122 
123  ShapeList & rotate(double angle) override;
124 
130  ShapeList rotated(double angle);
131 
132  ShapeList & translate(double dx, double dy) override;
133 
140  ShapeList translated(double dx, double dy);
141 
142  ShapeList & scale(double sx, double sy) override;
143 
144  ShapeList & scale(double s) override;
145 
152  ShapeList scaled(double sx, double sy) const;
153 
159  ShapeList scaled(double s) const;
160 
167  void scaleAll(double s) override;
168 
169  void flushPostscript(std::ostream & stream, const TransformEPS & transform) const override;
170 
171  void flushFIG(std::ostream & stream, const TransformFIG & transform, std::map<Color, int> & colormap) const override;
172 
173  void flushSVG(std::ostream & stream, const TransformSVG & transform) const override;
174 
175  void flushTikZ(std::ostream & stream, const TransformTikZ & transform) const override;
176 
177  Rect boundingBox(LineWidthFlag) const override;
178 
179  ShapeList * clone() const override;
180 
187  ShapeList & push_back(Shape * shape);
188 
198  ShapeList & operator<<(const Shape & shape);
199 
207  ShapeList & operator+=(const Shape & shape);
208 
219  ShapeList & append(const Shape & shape, Direction direction = ShapeList::Right, Alignment alignment = ShapeList::AlignCenter, double margin = 0.0, LineWidthFlag lineWidthFlag = UseLineWidth);
220 
233  Group & addTiling(const Shape & shape, Point topLeftCorner, std::size_t columns, std::size_t rows, double spacing = 0.0, LineWidthFlag lineWidthFlag = UseLineWidth);
234 
245  void repeat(const Shape & shape, unsigned int times, double dx, double dy, double scaleX = 1.0, double scaleY = 1.0, double angle = 0.0);
246 
252  ShapeList & dup(std::size_t copies = 1);
253 
260  template <typename T> T & last(const std::size_t position = 0);
261 
268  Shape & last(const std::size_t position = 0);
269 
275  template <typename T> T & topLevelFindLast(std::size_t position = 0);
276 
281  Shape & top();
282 
287  void accept(ShapeVisitor & visitor) override;
288 
294  void accept(const ShapeVisitor & visitor) override;
295 
301  void accept(ConstShapeVisitor & visitor) const override;
302 
308  void accept(const ConstShapeVisitor & visitor) const override;
309 
315  Shape * accept(CompositeShapeTransform & transform) const override;
316 
322  Shape * accept(const CompositeShapeTransform & transform) const override;
323 
330  inline TopLevelIterator(std::vector<Shape *>::iterator it);
331  inline Shape & operator*();
332  inline Shape * operator->();
333  inline Shape * pointer();
334  inline TopLevelIterator & operator++();
335  inline TopLevelIterator operator++(int);
336  inline bool operator==(const TopLevelIterator & other);
337  inline bool operator!=(const TopLevelIterator & other);
338 
339  private:
340  std::vector<Shape *>::iterator _it;
341  };
342 
349  inline TopLevelConstIterator(std::vector<Shape *>::const_iterator it);
350  inline const Shape & operator*();
351  inline const Shape * operator->();
352  inline const Shape * pointer();
353  inline TopLevelConstIterator & operator++();
354  inline TopLevelConstIterator operator++(int);
355  inline bool operator==(const TopLevelConstIterator & other);
356  inline bool operator!=(const TopLevelConstIterator & other);
357 
358  private:
359  std::vector<Shape *>::const_iterator _it;
360  };
361 
367  inline DepthFirstIterator();
368  inline DepthFirstIterator(ShapeList * list);
369  inline Shape & operator*();
370  inline Shape * operator->();
371  inline Shape * pointer();
372  inline bool operator==(const DepthFirstIterator & other);
373  inline bool operator!=(const DepthFirstIterator & other);
374  inline DepthFirstIterator & operator++();
375  inline DepthFirstIterator operator++(int);
376 
377  private:
378  void moveToFirstActuelShape();
379  void moveToNextActualShape();
380  std::stack<ShapeList *> _shapeListsStack;
381  std::stack<TopLevelIterator> _iteratorsStack;
382  };
383 
389  inline BreadthFirstIterator();
390  inline BreadthFirstIterator(ShapeList * list);
391  inline Shape & operator*();
392  inline Shape * operator->();
393  inline Shape * pointer();
394  inline bool operator==(const BreadthFirstIterator & other);
395  inline bool operator!=(const BreadthFirstIterator & other);
396  inline BreadthFirstIterator & operator++();
397  inline BreadthFirstIterator operator++(int);
398 
399  private:
400  void moveToFirstActuelShape();
401  void moveToNextActualShape();
402  std::queue<ShapeList *> _shapeListsQueue;
403  std::queue<TopLevelIterator> _iteratorsQueue;
404  };
405 
410  inline TopLevelIterator begin();
411 
416  inline TopLevelIterator end();
417 
422  inline TopLevelConstIterator begin() const;
423 
428  inline TopLevelConstIterator cbegin() const;
429 
434  inline TopLevelConstIterator end() const;
435 
440  inline TopLevelConstIterator cend() const;
441 
447 
453 
459 
465 
470  std::size_t deepSize() const;
471 
476  inline std::size_t size() const;
477 
478 private:
479  static const std::string _name;
481 protected:
482  void addShape(const Shape & shape, double scaleFactor);
483 
484  std::vector<Shape *> _shapes;
489  void deleteShapes();
490 };
491 
492 // Inline methods and functions
493 
494 #if defined(max)
495 #undef max
496 #define HAS_MSVC_MAX true
497 #endif
498 
499 ShapeList::ShapeList() {}
500 
501 template <typename T> T & ShapeList::last(const std::size_t position)
502 {
503  if (position < _shapes.size()) {
504  std::vector<Shape *>::reverse_iterator it = _shapes.rbegin() + static_cast<std::vector<Shape *>::difference_type>(position);
505  Shape * pshape = *it;
506  T * result = dynamic_cast<T *>(pshape);
507  if (!result) {
508  std::cerr << "Error: ShapeList::last<> called with invalid result type\n";
509  exit(-1);
510  }
511  return dynamic_cast<T &>(*result);
512  } else {
513  Tools::error << "Trying to access an element that does not exist (" << position << "/" << _shapes.size() << ").\n";
514  throw - 1;
515  }
516 }
517 
518 template <typename T> T & ShapeList::topLevelFindLast(std::size_t position)
519 {
520  std::vector<Shape *>::reverse_iterator it = _shapes.rbegin();
521  while (it != _shapes.rend()) {
522  T * shape = dynamic_cast<T *>(*it);
523  if (shape) {
524  if (!position) {
525  return *shape;
526  } else {
527  --position;
528  }
529  }
530  ++it;
531  }
532  throw Exception("topLevelFindLast<T>(): no such shape type found (" + std::string(typeid(T).name()) + ")");
533 }
534 
535 ShapeList::TopLevelIterator::TopLevelIterator(std::vector<Shape *>::iterator it) : _it(it) {}
536 
537 Shape & ShapeList::TopLevelIterator::operator*()
538 {
539  return **_it;
540 }
541 
542 Shape * ShapeList::TopLevelIterator::operator->()
543 {
544  return *_it;
545 }
546 
547 Shape * ShapeList::TopLevelIterator::pointer()
548 {
549  return *_it;
550 }
551 
552 ShapeList::TopLevelIterator & ShapeList::TopLevelIterator::operator++()
553 {
554  ++_it;
555  return *this;
556 }
557 
558 ShapeList::TopLevelIterator ShapeList::TopLevelIterator::operator++(int)
559 {
560  TopLevelIterator previous(*this);
561  ++_it;
562  return previous;
563 }
564 
565 bool ShapeList::TopLevelIterator::operator==(const TopLevelIterator & other)
566 {
567  return _it == other._it;
568 }
569 
570 bool ShapeList::TopLevelIterator::operator!=(const TopLevelIterator & other)
571 {
572  return _it != other._it;
573 }
574 
575 ShapeList::TopLevelConstIterator::TopLevelConstIterator(std::vector<Shape *>::const_iterator it) : _it(it) {}
576 
577 const Shape & ShapeList::TopLevelConstIterator::operator*()
578 {
579  return **_it;
580 }
581 
582 const Shape * ShapeList::TopLevelConstIterator::operator->()
583 {
584  return *_it;
585 }
586 
587 const Shape * ShapeList::TopLevelConstIterator::pointer()
588 {
589  return *_it;
590 }
591 
592 ShapeList::TopLevelConstIterator & ShapeList::TopLevelConstIterator::operator++()
593 {
594  ++_it;
595  return *this;
596 }
597 
598 ShapeList::TopLevelConstIterator ShapeList::TopLevelConstIterator::operator++(int)
599 {
600  TopLevelConstIterator previous(*this);
601  ++_it;
602  return previous;
603 }
604 
605 bool ShapeList::TopLevelConstIterator::operator==(const TopLevelConstIterator & other)
606 {
607  return _it == other._it;
608 }
609 
610 bool ShapeList::TopLevelConstIterator::operator!=(const TopLevelConstIterator & other)
611 {
612  return _it != other._it;
613 }
614 
616 {
617  return TopLevelIterator(_shapes.begin());
618 }
619 
621 {
622  return TopLevelIterator(_shapes.end());
623 }
624 
626 {
627  return TopLevelConstIterator(_shapes.begin());
628 }
629 
631 {
632  return TopLevelConstIterator(_shapes.begin());
633 }
634 
636 {
637  return TopLevelConstIterator(_shapes.end());
638 }
639 
641 {
642  return TopLevelConstIterator(_shapes.end());
643 }
644 
646 {
647  return DepthFirstIterator(this);
648 }
649 
651 {
652  return DepthFirstIterator();
653 }
654 
656 {
657  return BreadthFirstIterator(this);
658 }
659 
661 {
662  return BreadthFirstIterator();
663 }
664 
665 std::size_t ShapeList::size() const
666 {
667  return _shapes.size();
668 }
669 
670 ShapeList::DepthFirstIterator::DepthFirstIterator() {}
671 
672 ShapeList::DepthFirstIterator::DepthFirstIterator(ShapeList * list)
673 {
674  _shapeListsStack.push(list);
675  _iteratorsStack.push(list->begin());
676  moveToFirstActuelShape();
677 }
678 
679 Shape & ShapeList::DepthFirstIterator::operator*()
680 {
681  return *(_iteratorsStack.top());
682 }
683 
684 Shape * ShapeList::DepthFirstIterator::operator->()
685 {
686  return pointer();
687 }
688 
689 Shape * ShapeList::DepthFirstIterator::pointer()
690 {
691  return _iteratorsStack.top().pointer();
692 }
693 
694 bool ShapeList::DepthFirstIterator::operator==(const DepthFirstIterator & other)
695 {
696  return (_shapeListsStack.empty() && other._shapeListsStack.empty()) ||
697  ((!_shapeListsStack.empty() && !other._shapeListsStack.empty()) && (_shapeListsStack.top() == other._shapeListsStack.top()) && (_iteratorsStack.top() == other._iteratorsStack.top()));
698 }
699 
700 bool ShapeList::DepthFirstIterator::operator!=(const DepthFirstIterator & other)
701 {
702  return !(*this == other);
703 }
704 
705 ShapeList::DepthFirstIterator & ShapeList::DepthFirstIterator::operator++()
706 {
707  moveToNextActualShape();
708  return *this;
709 }
710 
711 ShapeList::DepthFirstIterator ShapeList::DepthFirstIterator::operator++(int)
712 {
713  DepthFirstIterator currentValue(*this);
714  moveToNextActualShape();
715  return currentValue;
716 }
717 
718 ShapeList::BreadthFirstIterator::BreadthFirstIterator() {}
719 
720 ShapeList::BreadthFirstIterator::BreadthFirstIterator(ShapeList * list)
721 {
722  _shapeListsQueue.push(list);
723  _iteratorsQueue.push(list->begin());
724  moveToFirstActuelShape();
725 }
726 
727 Shape & ShapeList::BreadthFirstIterator::operator*()
728 {
729  return *(_iteratorsQueue.front());
730 }
731 
732 Shape * ShapeList::BreadthFirstIterator::operator->()
733 {
734  return pointer();
735 }
736 
737 Shape * ShapeList::BreadthFirstIterator::pointer()
738 {
739  return _iteratorsQueue.front().pointer();
740 }
741 
742 bool ShapeList::BreadthFirstIterator::operator==(const BreadthFirstIterator & other)
743 {
744  return (_shapeListsQueue.empty() && other._shapeListsQueue.empty()) ||
745  ((!_shapeListsQueue.empty() && !other._shapeListsQueue.empty()) && (_shapeListsQueue.front() == other._shapeListsQueue.front()) && (_iteratorsQueue.front() == other._iteratorsQueue.front()));
746 }
747 
748 bool ShapeList::BreadthFirstIterator::operator!=(const BreadthFirstIterator & other)
749 {
750  return !(*this == other);
751 }
752 
753 ShapeList::BreadthFirstIterator & ShapeList::BreadthFirstIterator::operator++()
754 {
755  moveToNextActualShape();
756  return *this;
757 }
758 
759 ShapeList::BreadthFirstIterator ShapeList::BreadthFirstIterator::operator++(int)
760 {
761  BreadthFirstIterator currentValue(*this);
762  moveToNextActualShape();
763  return currentValue;
764 }
765 
766 #if defined(HAS_MSVC_MAX)
767 #define max(A, B) ((A) > (B) ? (A) : (B))
768 #endif
769 
770 } // namespace LibBoard
771 
772 #endif /* BOARD_SHAPELIST_H */
LibBoard::ShapeList::accept
void accept(ShapeVisitor &visitor) override
Accepts a visitor object.
Definition: ShapeList.cpp:457
Shape.h
@copyright This source code is part of the Board project, a C++ library whose purpose is to allow sim...
LibBoard::ShapeList::depthFirstBegin
DepthFirstIterator depthFirstBegin()
depthFirstBegin
Definition: ShapeList.h:645
LibBoard::ShapeList::last
T & last(const std::size_t position=0)
Definition: ShapeList.h:501
LibBoard::ShapeList::topLevelFindLast
T & topLevelFindLast(std::size_t position=0)
Definition: ShapeList.h:518
LibBoard::Exception
Definition: Exception.h:36
LibBoard::ShapeList::deepSize
std::size_t deepSize() const
Recursively counts the number of shapes in the list.
Definition: ShapeList.cpp:515
LibBoard::ShapeList::begin
TopLevelIterator begin()
begin
Definition: ShapeList.h:615
LibBoard::Shape::Shape
Shape()
Definition: Shape.h:329
LibBoard::ShapeList::breadthFirstEnd
BreadthFirstIterator breadthFirstEnd()
breadthFirstEnd
Definition: ShapeList.h:660
LibBoard::ShapeList::flushSVG
void flushSVG(std::ostream &stream, const TransformSVG &transform) const override
Definition: ShapeList.cpp:401
LibBoard::Rect
Struct representing a rectangle on the plane.
Definition: Rect.h:39
LibBoard::ShapeList::push_back
ShapeList & push_back(Shape *shape)
Definition: ShapeList.cpp:441
LibBoard::ShapeList::repeat
void repeat(const Shape &shape, unsigned int times, double dx, double dy, double scaleX=1.0, double scaleY=1.0, double angle=0.0)
Definition: ShapeList.cpp:231
LibBoard::ShapeList::rotate
ShapeList & rotate(double angle, const Point &center) override
Definition: ShapeList.cpp:301
LibBoard::ShapeList::flushFIG
void flushFIG(std::ostream &stream, const TransformFIG &transform, std::map< Color, int > &colormap) const override
Definition: ShapeList.cpp:394
LibBoard::ShapeList::depthFirstEnd
DepthFirstIterator depthFirstEnd()
depthFirstEnd
Definition: ShapeList.h:650
LibBoard::CompositeShapeTransform
A CompositeShapeTransform may be used to duplicate/transform a composite shape tree.
Definition: ShapeVisitor.h:103
LibBoard::ShapeList::dup
ShapeList & dup(std::size_t copies=1)
Definition: ShapeList.cpp:181
Exception.h
The Exception type. @copyright This source code is part of the Board project, a C++ library whose pur...
LibBoard::ShapeList::TopLevelConstIterator
The TopLevelConstIterator struct.
Definition: ShapeList.h:348
LibBoard::Point
Struct representing a 2D point.
Definition: Point.h:42
LibBoard::TransformEPS
Structure representing a scaling and translation suitable for an EPS output.
Definition: Transforms.h:71
LibBoard::ShapeList::BreadthFirstIterator
The BreadthFirstIterator struct allows to traverse the shape tree using a breadth-first strategy.
Definition: ShapeList.h:388
LibBoard::ShapeList::_shapes
std::vector< Shape * > _shapes
Definition: ShapeList.h:484
LibBoard::ShapeList::addTiling
Group & addTiling(const Shape &shape, Point topLeftCorner, std::size_t columns, std::size_t rows, double spacing=0.0, LineWidthFlag lineWidthFlag=UseLineWidth)
Definition: ShapeList.cpp:210
LibBoard::Shape
Abstract structure for a 2D shape.
Definition: Shape.h:63
LibBoard::ShapeList::translate
ShapeList & translate(double dx, double dy) override
Definition: ShapeList.cpp:328
LibBoard::ShapeList::top
Shape & top()
Definition: ShapeList.cpp:452
LibBoard::ConstShapeVisitor
A ConstShapeVisitor may visit const shapes of a composite shape tree in back-to-front order.
Definition: ShapeVisitor.h:78
LibBoard::ShapeList::translated
ShapeList translated(double dx, double dy)
Definition: ShapeList.cpp:339
LibBoard::ShapeList::breadthFirstBegin
BreadthFirstIterator breadthFirstBegin()
breadthFirstBegin
Definition: ShapeList.h:655
LibBoard::ShapeList::clear
ShapeList & clear()
Definition: ShapeList.cpp:86
LibBoard::TransformTikZ
Structure representing a scaling and translation suitable for an TikZ output.
Definition: Transforms.h:126
LibBoard::Group
A group of shapes. A group is basically a ShapeList except that when rendered in either an SVG of a F...
Definition: Group.h:40
LibBoard::ShapeList::size
std::size_t size() const
The number of shapes in the list (at top level).
Definition: ShapeList.h:665
LibBoard::TransformFIG
Structure representing a scaling and translation suitable for an XFig output.
Definition: Transforms.h:87
LibBoard::ShapeList
A group of shapes.
Definition: ShapeList.h:46
LibBoard::ShapeList::cbegin
TopLevelConstIterator cbegin() const
cbegin
Definition: ShapeList.h:630
LibBoard::ShapeList::scale
ShapeList & scale(double sx, double sy) override
Definition: ShapeList.cpp:344
LibBoard::Shape::center
virtual Point center(LineWidthFlag lineWidthFlag=IgnoreLineWidth) const
Definition: Shape.cpp:59
LibBoard::ShapeList::TopLevelIterator
The TopLevelIterator struct.
Definition: ShapeList.h:329
LibBoard::ShapeList::flushTikZ
void flushTikZ(std::ostream &stream, const TransformTikZ &transform) const override
Definition: ShapeList.cpp:410
LibBoard::ShapeList::end
TopLevelIterator end()
end
Definition: ShapeList.h:620
LibBoard::ShapeList::cend
TopLevelConstIterator cend() const
cend
Definition: ShapeList.h:640
LibBoard::ShapeList::flushPostscript
void flushPostscript(std::ostream &stream, const TransformEPS &transform) const override
Definition: ShapeList.cpp:385
LibBoard::ShapeList::rotated
ShapeList rotated(double angle, const Point &center)
Definition: ShapeList.cpp:312
LibBoard::ShapeList::deleteShapes
void deleteShapes()
Definition: ShapeList.cpp:93
LibBoard::ShapeList::DepthFirstIterator
The DepthFirstIterator struct allows to traverse the shape tree using a depth-first strategy.
Definition: ShapeList.h:366
LibBoard::ShapeList::scaleAll
void scaleAll(double s) override
Definition: ShapeList.cpp:376
LibBoard::ShapeList::clone
ShapeList * clone() const override
Definition: ShapeList.cpp:436
LibBoard::ShapeList::scaled
ShapeList scaled(double sx, double sy) const
Definition: ShapeList.cpp:366
LibBoard::ShapeList::operator<<
ShapeList & operator<<(const Shape &shape)
Definition: ShapeList.cpp:146
Tools.h
@copyright This source code is part of the Board project, a C++ library whose purpose is to allow sim...
LibBoard::ShapeList::name
const std::string & name() const override
Definition: ShapeList.cpp:49
LibBoard::ShapeList::operator+=
ShapeList & operator+=(const Shape &shape)
Definition: ShapeList.cpp:193
LibBoard::ShapeList::append
ShapeList & append(const Shape &shape, Direction direction=ShapeList::Right, Alignment alignment=ShapeList::AlignCenter, double margin=0.0, LineWidthFlag lineWidthFlag=UseLineWidth)
Definition: ShapeList.cpp:246
LibBoard::ShapeVisitor
A ShapeVisitor visits all shapes in a composite shape tree in back-to-front order.
Definition: ShapeVisitor.h:53
LibBoard::TransformSVG
Structure representing a scaling and translation suitable for an SVG output.
Definition: Transforms.h:109
LibBoard::ShapeList::boundingBox
Rect boundingBox(LineWidthFlag) const override
Definition: ShapeList.cpp:419