00001
00010 #ifndef _BOARD_SHAPES_H_
00011 #define _BOARD_SHAPES_H_
00012
00013 #include "board/Point.h"
00014 #include "board/Rect.h"
00015 #include "board/Color.h"
00016 #include "board/Transforms.h"
00017 #include "board/PSFonts.h"
00018 #include <string>
00019 #include <vector>
00020 #include <iostream>
00021 #include <map>
00022 #include <cmath>
00023
00024 #ifndef M_PI
00025 #define M_PI 3.14159265358979323846
00026 #endif
00027
00028 #ifndef M_PI_2
00029 #define M_PI_2 1.57079632679489661923
00030 #endif
00031
00032 namespace LibBoard {
00033
00038 struct Shape {
00039
00040 enum LineCap { ButtCap = 0, RoundCap, SquareCap };
00041 enum LineJoin { MiterJoin = 0, RoundJoin, BevelJoin };
00042
00051 Shape( Color penColor, Color fillColor,
00052 float lineWidth, const LineCap cap, const LineJoin join,
00053 int depth )
00054 : _depth( depth ), _penColor( penColor ), _fillColor( fillColor ),
00055 _lineWidth( lineWidth ), _lineCap( cap ), _lineJoin( join ) { }
00056
00060 virtual ~Shape() { }
00061
00067 virtual const std::string & name() const;
00068
00074 virtual Shape * clone() const = 0;
00075
00081 inline bool filled() const { return _fillColor != Color::None; }
00082
00088 virtual Point center() const = 0;
00089
00098 virtual Shape & rotate( double angle, const Point & center ) = 0;
00099
00107 virtual Shape & rotate( double angle ) = 0;
00108
00117 inline Shape & rotateDeg( double angle, const Point & center );
00118
00127 inline Shape & rotateDeg( double angle );
00128
00137 virtual Shape & translate( double dx, double dy ) = 0;
00138
00147 virtual Shape & scale( double sx, double sy ) = 0;
00148
00156 virtual Shape & scale( double s ) = 0;
00157
00163 virtual Rect boundingBox() const = 0;
00164
00165
00170 inline Rect bbox();
00171
00172
00178 inline Shape & operator--();
00179
00185 inline Shape & operator++();
00186
00187
00194 virtual void scaleAll( double s ) = 0;
00195
00196
00204 virtual void flushPostscript( std::ostream & stream,
00205 const TransformEPS & transform ) const = 0;
00206
00214 virtual void flushFIG( std::ostream & stream,
00215 const TransformFIG & transform,
00216 std::map<Color,int> & colormap ) const = 0;
00217
00225 virtual void flushSVG( std::ostream & stream,
00226 const TransformSVG & transform ) const = 0;
00227
00228 inline int depth() const;
00229
00230 virtual void depth( int );
00231
00232 virtual void shiftDepth( int shift );
00233
00234 inline const Color & penColor() const;
00235
00236 inline const Color & fillColor() const;
00237
00238 private:
00239 static const std::string _name;
00241 protected:
00242
00243 int _depth;
00244 Color _penColor;
00245 Color _fillColor;
00246 float _lineWidth;
00247 LineCap _lineCap;
00248 LineJoin _lineJoin;
00256 std::string svgProperties( const TransformSVG & transform ) const;
00257
00258
00264 std::string postscriptProperties() const;
00265
00266 };
00267
00268
00269 inline Rect
00270 Shape::bbox()
00271 {
00272 return this->boundingBox();
00273 }
00274
00275
00276 inline Shape &
00277 Shape::operator++()
00278 {
00279 ++_depth;
00280 return *this;
00281 }
00282
00283 inline Shape &
00284 Shape::operator--()
00285 {
00286 --_depth;
00287 return *this;
00288 }
00289
00290
00291 inline int
00292 Shape::depth() const
00293 {
00294 return _depth;
00295 }
00296
00297 inline const Color &
00298 Shape::penColor() const
00299 {
00300 return _penColor;
00301 }
00302
00303 const Color &
00304 Shape::fillColor() const
00305 {
00306 return _fillColor;
00307 }
00308
00309 Shape &
00310 Shape::rotateDeg( double angle, const Point & center )
00311 {
00312 return rotate( angle * ( M_PI / 180.0 ), center );
00313 }
00314
00315 Shape &
00316 Shape::rotateDeg( double angle )
00317 {
00318 return rotate( angle * ( M_PI / 180.0 ), center() );
00319 }
00320
00329 struct Dot : public Shape {
00330
00331 Dot( double x, double y,
00332 Color color,
00333 float lineWidth,
00334 int depth = -1 )
00335 : Shape( color, Color::None, lineWidth, RoundCap, MiterJoin, depth ),
00336 _x( x ), _y( y ) { }
00337
00343 const std::string & name() const;
00344
00345 Point center() const;
00346
00355 Shape & rotate( double angle, const Point & center );
00356
00365 Dot rotated( double angle, const Point & center ) const;
00366
00374 Shape & rotate( double angle );
00375
00383 Dot rotated( double angle ) const;
00384
00393 Shape & translate( double dx, double dy );
00394
00403 Dot translated( double dx, double dy ) const;
00404
00405 Shape & scale( double sx, double sy );
00406
00407 Shape & scale( double s );
00408
00419 Dot scaled( double sx, double sy ) const;
00420
00421 Dot scaled( double s ) const;
00422
00429 void scaleAll( double s );
00430
00431 void flushPostscript( std::ostream & stream,
00432 const TransformEPS & transform ) const;
00433
00434 void flushFIG( std::ostream & stream,
00435 const TransformFIG & transform,
00436 std::map<Color,int> & colormap ) const;
00437
00438 void flushSVG( std::ostream & stream,
00439 const TransformSVG & transform ) const;
00440
00441 Rect boundingBox() const;
00442
00443 Shape * clone() const;
00444
00445 private:
00446 static const std::string _name;
00448 protected:
00449 double _x;
00450 double _y;
00451 };
00452
00457 struct Line : public Shape {
00458
00470 Line( double x1, double y1, double x2, double y2,
00471 Color color,
00472 float lineWidth, const LineCap cap = ButtCap, const LineJoin join = MiterJoin,
00473 int depth = -1 )
00474 : Shape( color, Color::None, lineWidth, cap, join, depth ),
00475 _x1( x1 ), _y1( y1 ), _x2( x2 ), _y2( y2 ) { }
00476
00482 const std::string & name() const;
00483
00484 Point center() const;
00485
00486 Shape & rotate( double angle, const Point & center );
00487
00496 Line rotated( double angle, const Point & center ) const;
00497
00498 Shape & rotate( double angle );
00499
00507 Line rotated( double angle ) const;
00508
00509 Shape & translate( double dx, double dy );
00510
00519 Line translated( double dx, double dy ) const;
00520
00521 Shape & scale( double sx, double sy );
00522
00523 Shape & scale( double s );
00524
00533 Line scaled( double sx, double sy ) const;
00534
00535 Line scaled( double s ) const;
00536
00543 void scaleAll( double s );
00544
00545 void flushPostscript( std::ostream & stream,
00546 const TransformEPS & transform ) const;
00547
00548 void flushFIG( std::ostream & stream,
00549 const TransformFIG & transform,
00550 std::map<Color,int> & colormap ) const;
00551
00552 void flushSVG( std::ostream & stream,
00553 const TransformSVG & transform ) const;
00554
00555 Rect boundingBox() const;
00556
00557 Shape * clone() const;
00558
00559 private:
00560 static const std::string _name;
00562 protected:
00563 double _x1;
00564 double _y1;
00565 double _x2;
00566 double _y2;
00567 };
00568
00573 struct Arrow : public Line {
00574
00587 Arrow( double x1, double y1, double x2, double y2,
00588 Color penColor, Color fillColor,
00589 float lineWidth, const LineCap cap = ButtCap, const LineJoin join = MiterJoin,
00590 int depth = -1 )
00591 : Line( x1, y1, x2, y2, penColor, lineWidth, cap, join, depth ) {
00592 Shape::_fillColor = fillColor;
00593 }
00594
00600 const std::string & name() const;
00601
00610 Arrow rotated( double angle, const Point & center ) const;
00611
00619 Arrow rotated( double angle ) const;
00620
00629 Arrow translated( double dx, double dy ) const;
00630
00639 Arrow scaled( double sx, double sy ) const;
00640
00641 Arrow scaled( double s ) const;
00642
00643 void flushPostscript( std::ostream & stream,
00644 const TransformEPS & transform ) const;
00645
00646 void flushFIG( std::ostream & stream,
00647 const TransformFIG & transform,
00648 std::map<Color,int> & colormap ) const;
00649 void flushSVG( std::ostream & stream,
00650 const TransformSVG & transform ) const;
00651
00652 Shape * clone() const;
00653
00654 private:
00655 static const std::string _name;
00656 };
00657
00662 struct Polyline : public Shape {
00663 Polyline( const std::vector<Point> & points,
00664 bool closed,
00665 Color penColor, Color fillColor,
00666 float lineWidth, const LineCap cap = ButtCap, const LineJoin join = MiterJoin,
00667 int depth = -1 )
00668 : Shape( penColor, fillColor, lineWidth, cap, join, depth ),
00669 _points( points ), _closed( closed ) { }
00670
00671 Polyline( bool closed, Color penColor, Color fillColor,
00672 float lineWidth, const LineCap cap = ButtCap, const LineJoin join = MiterJoin,
00673 int depth = -1 )
00674 : Shape( penColor, fillColor, lineWidth, cap, join, depth ),
00675 _closed( closed ) { }
00676
00682 const std::string & name() const;
00683
00684 Point center() const;
00685
00693 Polyline & operator<<( const Point & p );
00694
00702 Point & operator[]( const unsigned int n ) {
00703 return _points[ n ];
00704 }
00705
00706
00707 Shape & rotate( double angle, const Point & center );
00708
00717 Polyline rotated( double angle, const Point & center ) const;
00718
00719 Shape & rotate( double angle );
00720
00728 Polyline rotated( double angle ) const;
00729
00730 Shape & translate( double dx, double dy );
00731
00740 Polyline translated( double dx, double dy ) const;
00741
00742 Shape & scale( double sx, double sy );
00743
00744 Shape & scale( double s );
00745
00754 Polyline scaled( double sx, double sy ) const;
00755
00756 Polyline scaled( double s ) const;
00757
00764 void scaleAll( double s );
00765
00766 void flushPostscript( std::ostream & stream,
00767 const TransformEPS & transform ) const;
00768
00769 void flushFIG( std::ostream & stream,
00770 const TransformFIG & transform,
00771 std::map<Color,int> & colormap ) const;
00772
00773 void flushSVG( std::ostream & stream,
00774 const TransformSVG & transform ) const;
00775
00776 Rect boundingBox() const;
00777
00778 Shape * clone() const;
00779
00780 private:
00781 static const std::string _name;
00783 protected:
00784 std::vector<Point> _points;
00785 bool _closed;
00786 };
00787
00792 struct Rectangle : public Polyline {
00793
00794 Rectangle( double x, double y, double width, double height,
00795 Color penColor, Color fillColor,
00796 float lineWidth, const LineCap cap = ButtCap, const LineJoin join = MiterJoin,
00797 int depth = -1 )
00798 : Polyline( std::vector<Point>(), true, penColor, fillColor, lineWidth, cap, join, depth ) {
00799 _points.push_back( Point( x, y ) );
00800 _points.push_back( Point( x + width, y ) );
00801 _points.push_back( Point( x + width, y - height ) );
00802 _points.push_back( Point( x, y - height ) );
00803 }
00804
00805 Rectangle( const Rect & rect,
00806 Color penColor, Color fillColor,
00807 float lineWidth, const LineCap cap = ButtCap, const LineJoin join = MiterJoin,
00808 int depth = -1 )
00809 : Polyline( std::vector<Point>(), true, penColor, fillColor, lineWidth, cap, join, depth ) {
00810 _points.push_back( Point( rect.left, rect.top ) );
00811 _points.push_back( Point( rect.left + rect.width, rect.top ) );
00812 _points.push_back( Point( rect.left + rect.width, rect.top - rect.height ) );
00813 _points.push_back( Point( rect.left, rect.top - rect.height ) );
00814 }
00815
00821 const std::string & name() const;
00822
00823 double x() const { return _points[0].x; }
00824 double y() const { return _points[0].y; }
00825 double width() { return (_points[1] - _points[0]).norm(); }
00826 double height() { return (_points[0] - _points[3]).norm(); }
00827 Point topLeft() { return Point( _points[0].x, _points[0].y ); }
00828 Point topRight() { return Point( _points[1].x, _points[1].y ); }
00829 Point bottomLeft() { return Point( _points[3].x, _points[3].y ); }
00830 Point bottomRight() { return Point( _points[2].x, _points[2].y ); }
00831
00832
00841 Rectangle rotated( double angle, const Point & center ) const;
00842
00850 Rectangle rotated( double angle ) const;
00851
00860 Rectangle translated( double dx, double dy ) const;
00861
00870 Rectangle scaled( double sx, double sy ) const;
00871
00872 Rectangle scaled( double s ) const;
00873
00880 void scaleAll( double s );
00881
00882 void flushFIG( std::ostream & stream,
00883 const TransformFIG & transform,
00884 std::map<Color,int> & colormap ) const;
00885
00886 void flushSVG( std::ostream & stream,
00887 const TransformSVG & transform ) const;
00888
00889 Shape * clone() const;
00890
00891 private:
00892 static const std::string _name;
00894 protected:
00895 bool _isRectangle;
00896 };
00897
00898
00903 struct Triangle : public Polyline {
00904
00905 Triangle( const Point & p1, const Point & p2, const Point & p3,
00906 Color penColor, Color fillColor,
00907 float lineWidth, const LineCap cap = ButtCap, const LineJoin join = MiterJoin,
00908 int depth = -1 )
00909 : Polyline( std::vector<Point>(), true, penColor, fillColor, lineWidth, cap, join, depth ) {
00910 _points.push_back( p1 );
00911 _points.push_back( p2 );
00912 _points.push_back( p3 );
00913 }
00914
00915 Triangle( const double x1, const double y1,
00916 const double x2, const double y2,
00917 const double x3, const double y3,
00918 Color penColor, Color fillColor,
00919 float lineWidth, const LineCap cap = ButtCap, const LineJoin join = MiterJoin,
00920 int depth = -1 )
00921 : Polyline( std::vector<Point>(), true, penColor, fillColor, lineWidth, cap, join, depth ) {
00922 _points.push_back( Point( x1, y1 ) );
00923 _points.push_back( Point( x2, y2 ) );
00924 _points.push_back( Point( x3, y3 ) );
00925 }
00926
00932 const std::string & name() const;
00933
00934 Triangle rotated( double angle ) const;
00935
00944 Triangle translated( double dx, double dy ) const;
00945
00954 Triangle scaled( double sx, double sy ) const;
00955
00956 Triangle scaled( double s ) const;
00957
00958 Shape * clone() const;
00959
00960 private:
00961 static const std::string _name;
00963 protected:
00964 };
00965
00966
00971 struct GouraudTriangle : public Polyline {
00972
00973
00974 GouraudTriangle( const Point & p0, const Color & color0,
00975 const Point & p1, const Color & color1,
00976 const Point & p2, const Color & color2,
00977 int subdivisions,
00978 int depth = -1 );
00979
00980 GouraudTriangle( const Point & p0, float brightness0,
00981 const Point & p1, float brightness1,
00982 const Point & p2, float brightness2,
00983 const Color & fillColor,
00984 int subdivisions,
00985 int depth = -1 );
00986
00992 const std::string & name() const;
00993
00994 Point center() const;
00995
00996 Shape & rotate( double angle, const Point & center );
00997
00998 GouraudTriangle rotated( double angle, const Point & center ) const;
00999
01000 Shape & rotate( double angle );
01001
01002 GouraudTriangle rotated( double angle ) const;
01003
01012 GouraudTriangle translated( double dx, double dy ) const;
01013
01022 GouraudTriangle scaled( double sx, double sy ) const;
01023
01024 GouraudTriangle scaled( double s ) const;
01025
01026
01033 void scaleAll( double s );
01034
01041 void flushPostscript( std::ostream & stream,
01042 const TransformEPS & transform ) const;
01043
01056 void flushFIG( std::ostream & stream,
01057 const TransformFIG & transform,
01058 std::map<Color,int> & colormap ) const;
01059
01060 void flushSVG( std::ostream & stream,
01061 const TransformSVG & transform ) const;
01062
01063 Shape * clone() const;
01064
01065 private:
01066 static const std::string _name;
01068 protected:
01069 Color _color0;
01070 Color _color1;
01071 Color _color2;
01072 int _subdivisions;
01073 };
01074
01079 struct Ellipse : public Shape {
01080
01081 Ellipse( double x, double y,
01082 double xRadius, double yRadius,
01083 Color penColor, Color fillColor,
01084 float lineWidth, int depth = -1 )
01085 : Shape( penColor, fillColor, lineWidth, ButtCap, MiterJoin, depth ),
01086 _center( x, y ), _xRadius( xRadius ), _yRadius( yRadius ), _angle( 0.0 ),
01087 _circle( false ) {
01088 while ( _angle > M_PI_2 ) _angle -= M_PI;
01089 while ( _angle < -M_PI_2 ) _angle += M_PI;
01090 }
01091
01097 const std::string & name() const;
01098
01099 Point center() const;
01100
01101 Shape & rotate( double angle, const Point & center );
01102
01111 Ellipse rotated( double angle, const Point & center ) const;
01112
01113 Shape & rotate( double angle );
01114
01122 Ellipse rotated( double angle ) const;
01123
01124 Shape & translate( double dx, double dy );
01125
01134 Ellipse translated( double dx, double dy ) const;
01135
01136 Shape & scale( double sx, double sy );
01137
01138 Shape & scale( double s );
01139
01148 Ellipse scaled( double sx, double sy ) const;
01149
01150 Ellipse scaled( double s ) const;
01151
01158 void scaleAll( double s );
01159
01160 void flushPostscript( std::ostream & stream,
01161 const TransformEPS & transform ) const;
01162
01163 void flushFIG( std::ostream & stream,
01164 const TransformFIG & transform,
01165 std::map<Color,int> & colormap ) const;
01166
01167 void flushSVG( std::ostream & stream,
01168 const TransformSVG & transform ) const;
01169
01170 Rect boundingBox() const;
01171
01172 Shape * clone() const;
01173
01174 private:
01175 static const std::string _name;
01177 protected:
01178 Point _center;
01179 double _xRadius;
01180 double _yRadius;
01181 double _angle;
01182 bool _circle;
01183 };
01184
01189 struct Circle : public Ellipse {
01190
01191 Circle( double x, double y, double radius,
01192 Color penColor, Color fillColor,
01193 float lineWidth,
01194 int depth = -1 )
01195 : Ellipse( x, y, radius, radius, penColor, fillColor, lineWidth, depth )
01196 { _circle = true; }
01197
01203 const std::string & name() const;
01204
01205 Point center() const;
01206
01207 Shape & rotate( double angle, const Point & center );
01208
01209 Circle rotated( double angle, const Point & center ) const;
01210
01211 Shape & rotate( double angle );
01212
01213 Circle rotated( double angle ) const;
01214
01215 Shape & translate( double dx, double dy );
01216
01217 Circle translated( double dx, double dy ) const;
01218
01219 Shape & scale( double sx, double sy );
01220
01221 Shape & scale( double s );
01222
01223 Circle scaled( double sx, double sy ) const;
01224
01225 Circle scaled( double s ) const;
01226
01233 void scaleAll( double s );
01234
01235 void flushSVG( std::ostream & stream,
01236 const TransformSVG & transform ) const;
01237
01238 Shape * clone() const;
01239
01240 private:
01241 static const std::string _name;
01242 };
01243
01248 struct Text : public Shape {
01249
01263 Text( double x, double y,
01264 const std::string & text,
01265 const Fonts::Font font,
01266 float size,
01267 Color color = Color::Black,
01268 int depth = -1 )
01269 : Shape( color, Color::None, 1.0, ButtCap, MiterJoin, depth ),
01270 _position( x, y ), _text( text ), _font( font ),
01271 _angle( 0.0 ), _size( size ),
01272 _xScale( 1.0 ), _yScale( 1.0 ) { }
01273
01274
01289 Text( double x, double y,
01290 const std::string & text,
01291 const Fonts::Font font,
01292 const std::string & svgFont,
01293 float size,
01294 Color color = Color::Black,
01295 int depth = -1 )
01296 : Shape( color, Color::None, 1.0, ButtCap, MiterJoin, depth ),
01297 _position( x, y ),
01298 _text( text ), _font( font ), _svgFont( svgFont ),
01299 _angle( 0.0 ),
01300 _size( size ),
01301 _xScale( 1.0 ), _yScale( 1.0 ) { }
01302
01308 const std::string & name() const;
01309
01310 Point center() const;
01311
01312 Shape & rotate( double angle, const Point & center );
01313
01314 Text rotated( double angle, const Point & center ) const;
01315
01316 Shape & rotate( double angle );
01317
01318 Text rotated( double angle ) const;
01319
01320 Shape & translate( double dx, double dy );
01321
01322 Text translated( double dx, double dy ) const;
01323
01324 Shape & scale( double sx, double sy );
01325
01326 Shape & scale( double s );
01327
01328 Text scaled( double sx, double sy ) const;
01329
01330 Text scaled( double s ) const;
01331
01338 void scaleAll( double s );
01339
01340 void flushPostscript( std::ostream & stream,
01341 const TransformEPS & transform ) const;
01342
01343 void flushFIG( std::ostream & stream,
01344 const TransformFIG & transform,
01345 std::map<Color,int> & colormap ) const;
01346
01347 void flushSVG( std::ostream & stream,
01348 const TransformSVG & transform ) const;
01349
01350 Rect boundingBox() const;
01351
01352 Shape * clone() const;
01353
01354 private:
01355 static const std::string _name;
01357 protected:
01358 Point _position;
01359 std::string _text;
01360 Fonts::Font _font;
01361 std::string _svgFont;
01362 double _angle;
01363 float _size;
01364 double _xScale;
01365 double _yScale;
01366 };
01367
01376 bool shapeGreaterDepth( const Shape *s1, const Shape *s2 );
01377
01378 }
01379
01380
01381
01382 #endif
01383