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/Path.h"
00016 #include "board/Color.h"
00017 #include "board/Transforms.h"
00018 #include "board/PSFonts.h"
00019 #include <string>
00020 #include <vector>
00021 #include <iostream>
00022 #include <map>
00023 #include <cmath>
00024
00025 #ifndef M_PI
00026 #define M_PI 3.14159265358979323846
00027 #endif
00028
00029 #ifndef M_PI_2
00030 #define M_PI_2 1.57079632679489661923
00031 #endif
00032
00033 namespace LibBoard {
00034
00039 struct Shape {
00040
00041 enum LineCap { ButtCap = 0, RoundCap, SquareCap };
00042 enum LineJoin { MiterJoin = 0, RoundJoin, BevelJoin };
00043
00052 Shape( Color penColor, Color fillColor,
00053 float lineWidth, const LineCap cap, const LineJoin join,
00054 int depth )
00055 : _depth( depth ), _penColor( penColor ), _fillColor( fillColor ),
00056 _lineWidth( lineWidth ), _lineCap( cap ), _lineJoin( join ) { }
00057
00061 virtual ~Shape() { }
00062
00068 virtual const std::string & name() const;
00069
00075 virtual Shape * clone() const = 0;
00076
00082 inline bool filled() const { return _fillColor != Color::None; }
00083
00089 virtual Point center() const = 0;
00090
00099 virtual Shape & rotate( double angle, const Point & center ) = 0;
00100
00108 virtual Shape & rotate( double angle ) = 0;
00109
00118 inline Shape & rotateDeg( double angle, const Point & center );
00119
00128 inline Shape & rotateDeg( double angle );
00129
00138 virtual Shape & translate( double dx, double dy ) = 0;
00139
00148 virtual Shape & scale( double sx, double sy ) = 0;
00149
00157 virtual Shape & scale( double s ) = 0;
00158
00164 virtual Rect boundingBox() const = 0;
00165
00166
00171 inline Rect bbox();
00172
00173
00179 inline Shape & operator--();
00180
00186 inline Shape & operator++();
00187
00188
00195 virtual void scaleAll( double s ) = 0;
00196
00197
00205 virtual void flushPostscript( std::ostream & stream,
00206 const TransformEPS & transform ) const = 0;
00207
00215 virtual void flushFIG( std::ostream & stream,
00216 const TransformFIG & transform,
00217 std::map<Color,int> & colormap ) const = 0;
00218
00226 virtual void flushSVG( std::ostream & stream,
00227 const TransformSVG & transform ) const = 0;
00228
00229 inline int depth() const;
00230
00231 virtual void depth( int );
00232
00233 virtual void shiftDepth( int shift );
00234
00235 inline const Color & penColor() const;
00236
00237 inline const Color & fillColor() const;
00238
00239 private:
00240 static const std::string _name;
00242 protected:
00243
00244 int _depth;
00245 Color _penColor;
00246 Color _fillColor;
00247 float _lineWidth;
00248 LineCap _lineCap;
00249 LineJoin _lineJoin;
00257 std::string svgProperties( const TransformSVG & transform ) const;
00258
00259
00265 std::string postscriptProperties() const;
00266
00267 };
00268
00269
00270 inline Rect
00271 Shape::bbox()
00272 {
00273 return this->boundingBox();
00274 }
00275
00276
00277 inline Shape &
00278 Shape::operator++()
00279 {
00280 ++_depth;
00281 return *this;
00282 }
00283
00284 inline Shape &
00285 Shape::operator--()
00286 {
00287 --_depth;
00288 return *this;
00289 }
00290
00291
00292 inline int
00293 Shape::depth() const
00294 {
00295 return _depth;
00296 }
00297
00298 inline const Color &
00299 Shape::penColor() const
00300 {
00301 return _penColor;
00302 }
00303
00304 const Color &
00305 Shape::fillColor() const
00306 {
00307 return _fillColor;
00308 }
00309
00310 Shape &
00311 Shape::rotateDeg( double angle, const Point & center )
00312 {
00313 return rotate( angle * ( M_PI / 180.0 ), center );
00314 }
00315
00316 Shape &
00317 Shape::rotateDeg( double angle )
00318 {
00319 return rotate( angle * ( M_PI / 180.0 ), center() );
00320 }
00321
00330 struct Dot : public Shape {
00331
00332 Dot( double x, double y,
00333 Color color,
00334 float lineWidth,
00335 int depth = -1 )
00336 : Shape( color, Color::None, lineWidth, RoundCap, MiterJoin, depth ),
00337 _x( x ), _y( y ) { }
00338
00344 const std::string & name() const;
00345
00346 Point center() const;
00347
00356 Shape & rotate( double angle, const Point & center );
00357
00366 Dot rotated( double angle, const Point & center ) const;
00367
00375 Shape & rotate( double angle );
00376
00384 Dot rotated( double angle ) const;
00385
00394 Shape & translate( double dx, double dy );
00395
00404 Dot translated( double dx, double dy ) const;
00405
00406 Shape & scale( double sx, double sy );
00407
00408 Shape & scale( double s );
00409
00420 Dot scaled( double sx, double sy ) const;
00421
00422 Dot scaled( double s ) const;
00423
00430 void scaleAll( double s );
00431
00432 void flushPostscript( std::ostream & stream,
00433 const TransformEPS & transform ) const;
00434
00435 void flushFIG( std::ostream & stream,
00436 const TransformFIG & transform,
00437 std::map<Color,int> & colormap ) const;
00438
00439 void flushSVG( std::ostream & stream,
00440 const TransformSVG & transform ) const;
00441
00442 Rect boundingBox() const;
00443
00444 Shape * clone() const;
00445
00446 private:
00447 static const std::string _name;
00449 protected:
00450 double _x;
00451 double _y;
00452 };
00453
00458 struct Line : public Shape {
00459
00471 Line( double x1, double y1, double x2, double y2,
00472 Color color,
00473 float lineWidth, const LineCap cap = ButtCap, const LineJoin join = MiterJoin,
00474 int depth = -1 )
00475 : Shape( color, Color::None, lineWidth, cap, join, depth ),
00476 _x1( x1 ), _y1( y1 ), _x2( x2 ), _y2( y2 ) { }
00477
00483 const std::string & name() const;
00484
00485 Point center() const;
00486
00487 Shape & rotate( double angle, const Point & center );
00488
00497 Line rotated( double angle, const Point & center ) const;
00498
00499 Shape & rotate( double angle );
00500
00508 Line rotated( double angle ) const;
00509
00510 Shape & translate( double dx, double dy );
00511
00520 Line translated( double dx, double dy ) const;
00521
00522 Shape & scale( double sx, double sy );
00523
00524 Shape & scale( double s );
00525
00534 Line scaled( double sx, double sy ) const;
00535
00536 Line scaled( double s ) const;
00537
00544 void scaleAll( double s );
00545
00546 void flushPostscript( std::ostream & stream,
00547 const TransformEPS & transform ) const;
00548
00549 void flushFIG( std::ostream & stream,
00550 const TransformFIG & transform,
00551 std::map<Color,int> & colormap ) const;
00552
00553 void flushSVG( std::ostream & stream,
00554 const TransformSVG & transform ) const;
00555
00556 Rect boundingBox() const;
00557
00558 Shape * clone() const;
00559
00560 private:
00561 static const std::string _name;
00563 protected:
00564 double _x1;
00565 double _y1;
00566 double _x2;
00567 double _y2;
00568 };
00569
00574 struct Arrow : public Line {
00575
00588 Arrow( double x1, double y1, double x2, double y2,
00589 Color penColor, Color fillColor,
00590 float lineWidth, const LineCap cap = ButtCap, const LineJoin join = MiterJoin,
00591 int depth = -1 )
00592 : Line( x1, y1, x2, y2, penColor, lineWidth, cap, join, depth ) {
00593 Shape::_fillColor = fillColor;
00594 }
00595
00601 const std::string & name() const;
00602
00611 Arrow rotated( double angle, const Point & center ) const;
00612
00620 Arrow rotated( double angle ) const;
00621
00630 Arrow translated( double dx, double dy ) const;
00631
00640 Arrow scaled( double sx, double sy ) const;
00641
00642 Arrow scaled( double s ) const;
00643
00644 void flushPostscript( std::ostream & stream,
00645 const TransformEPS & transform ) const;
00646
00647 void flushFIG( std::ostream & stream,
00648 const TransformFIG & transform,
00649 std::map<Color,int> & colormap ) const;
00650 void flushSVG( std::ostream & stream,
00651 const TransformSVG & transform ) const;
00652
00653 Shape * clone() const;
00654
00655 private:
00656 static const std::string _name;
00657 };
00658
00663 struct Polyline : public Shape {
00664 Polyline( const std::vector<Point> & points,
00665 bool closed,
00666 Color penColor, Color fillColor,
00667 float lineWidth, const LineCap cap = ButtCap, const LineJoin join = MiterJoin,
00668 int depth = -1 )
00669 : Shape( penColor, fillColor, lineWidth, cap, join, depth ),
00670 _path( points, closed ) { }
00671
00672 Polyline( const Path & path,
00673 Color penColor, Color fillColor,
00674 float lineWidth, const LineCap cap = ButtCap, const LineJoin join = MiterJoin,
00675 int depth = -1 )
00676 : Shape( penColor, fillColor, lineWidth, cap, join, depth ),
00677 _path( path ) { }
00678
00679 Polyline( bool closed, Color penColor, Color fillColor,
00680 float lineWidth, const LineCap cap = ButtCap, const LineJoin join = MiterJoin,
00681 int depth = -1 )
00682 : Shape( penColor, fillColor, lineWidth, cap, join, depth ),
00683 _path( closed ) { }
00684
00690 const std::string & name() const;
00691
00692 Point center() const;
00693
00701 Polyline & operator<<( const Point & p );
00702
00710 Point & operator[]( const unsigned int n ) {
00711 return _path[ n ];
00712 }
00713
00714
00715 Shape & rotate( double angle, const Point & center );
00716
00725 Polyline rotated( double angle, const Point & center ) const;
00726
00727 Shape & rotate( double angle );
00728
00736 Polyline rotated( double angle ) const;
00737
00738 Shape & translate( double dx, double dy );
00739
00748 Polyline translated( double dx, double dy ) const;
00749
00750 Shape & scale( double sx, double sy );
00751
00752 Shape & scale( double s );
00753
00762 Polyline scaled( double sx, double sy ) const;
00763
00764 Polyline scaled( double s ) const;
00765
00772 void scaleAll( double s );
00773
00774 void flushPostscript( std::ostream & stream,
00775 const TransformEPS & transform ) const;
00776
00777 void flushFIG( std::ostream & stream,
00778 const TransformFIG & transform,
00779 std::map<Color,int> & colormap ) const;
00780
00781 void flushSVG( std::ostream & stream,
00782 const TransformSVG & transform ) const;
00783
00784 Rect boundingBox() const;
00785
00786 Shape * clone() const;
00787
00788 private:
00789 static const std::string _name;
00791 protected:
00792 Path _path;
00793 };
00794
00799 struct Rectangle : public Polyline {
00800
00801 Rectangle( double x, double y, double width, double height,
00802 Color penColor, Color fillColor,
00803 float lineWidth, const LineCap cap = ButtCap, const LineJoin join = MiterJoin,
00804 int depth = -1 )
00805 : Polyline( std::vector<Point>(), true, penColor, fillColor, lineWidth, cap, join, depth ) {
00806 _path << Point( x, y );
00807 _path << Point( x + width, y );
00808 _path << Point( x + width, y - height );
00809 _path << Point( x, y - height );
00810 }
00811
00812 Rectangle( const Rect & rect,
00813 Color penColor, Color fillColor,
00814 float lineWidth, const LineCap cap = ButtCap, const LineJoin join = MiterJoin,
00815 int depth = -1 )
00816 : Polyline( std::vector<Point>(), true, penColor, fillColor, lineWidth, cap, join, depth ) {
00817 _path << Point( rect.left, rect.top );
00818 _path << Point( rect.left + rect.width, rect.top );
00819 _path << Point( rect.left + rect.width, rect.top - rect.height );
00820 _path << Point( rect.left, rect.top - rect.height );
00821 }
00822
00828 const std::string & name() const;
00829
00830 double x() const { return _path[0].x; }
00831 double y() const { return _path[0].y; }
00832 double width() { return (_path[1] - _path[0]).norm(); }
00833 double height() { return (_path[0] - _path[3]).norm(); }
00834 Point topLeft() { return Point( _path[0].x, _path[0].y ); }
00835 Point topRight() { return Point( _path[1].x, _path[1].y ); }
00836 Point bottomLeft() { return Point( _path[3].x, _path[3].y ); }
00837 Point bottomRight() { return Point( _path[2].x, _path[2].y ); }
00838
00839
00848 Rectangle rotated( double angle, const Point & center ) const;
00849
00857 Rectangle rotated( double angle ) const;
00858
00867 Rectangle translated( double dx, double dy ) const;
00868
00877 Rectangle scaled( double sx, double sy ) const;
00878
00879 Rectangle scaled( double s ) const;
00880
00887 void scaleAll( double s );
00888
00889 void flushFIG( std::ostream & stream,
00890 const TransformFIG & transform,
00891 std::map<Color,int> & colormap ) const;
00892
00893 void flushSVG( std::ostream & stream,
00894 const TransformSVG & transform ) const;
00895
00896 Shape * clone() const;
00897
00898 private:
00899 static const std::string _name;
00901 protected:
00902 bool _isRectangle;
00903 };
00904
00905
00910 struct Triangle : public Polyline {
00911
00912 Triangle( const Point & p1, const Point & p2, const Point & p3,
00913 Color penColor, Color fillColor,
00914 float lineWidth, const LineCap cap = ButtCap, const LineJoin join = MiterJoin,
00915 int depth = -1 )
00916 : Polyline( std::vector<Point>(), true, penColor, fillColor, lineWidth, cap, join, depth ) {
00917 _path << p1;
00918 _path << p2;
00919 _path << p3;
00920 }
00921
00922 Triangle( const double x1, const double y1,
00923 const double x2, const double y2,
00924 const double x3, const double y3,
00925 Color penColor, Color fillColor,
00926 float lineWidth, const LineCap cap = ButtCap, const LineJoin join = MiterJoin,
00927 int depth = -1 )
00928 : Polyline( std::vector<Point>(), true, penColor, fillColor, lineWidth, cap, join, depth ) {
00929 _path << Point( x1, y1 );
00930 _path << Point( x2, y2 );
00931 _path << Point( x3, y3 );
00932 }
00933
00939 const std::string & name() const;
00940
00941 Triangle rotated( double angle ) const;
00942
00951 Triangle translated( double dx, double dy ) const;
00952
00961 Triangle scaled( double sx, double sy ) const;
00962
00963 Triangle scaled( double s ) const;
00964
00965 Shape * clone() const;
00966
00967 private:
00968 static const std::string _name;
00970 protected:
00971 };
00972
00973
00978 struct GouraudTriangle : public Polyline {
00979
00980
00981 GouraudTriangle( const Point & p0, const Color & color0,
00982 const Point & p1, const Color & color1,
00983 const Point & p2, const Color & color2,
00984 int subdivisions,
00985 int depth = -1 );
00986
00987 GouraudTriangle( const Point & p0, float brightness0,
00988 const Point & p1, float brightness1,
00989 const Point & p2, float brightness2,
00990 const Color & fillColor,
00991 int subdivisions,
00992 int depth = -1 );
00993
00999 const std::string & name() const;
01000
01001 Point center() const;
01002
01003 Shape & rotate( double angle, const Point & center );
01004
01005 GouraudTriangle rotated( double angle, const Point & center ) const;
01006
01007 Shape & rotate( double angle );
01008
01009 GouraudTriangle rotated( double angle ) const;
01010
01019 GouraudTriangle translated( double dx, double dy ) const;
01020
01029 GouraudTriangle scaled( double sx, double sy ) const;
01030
01031 GouraudTriangle scaled( double s ) const;
01032
01033
01040 void scaleAll( double s );
01041
01048 void flushPostscript( std::ostream & stream,
01049 const TransformEPS & transform ) const;
01050
01063 void flushFIG( std::ostream & stream,
01064 const TransformFIG & transform,
01065 std::map<Color,int> & colormap ) const;
01066
01067 void flushSVG( std::ostream & stream,
01068 const TransformSVG & transform ) const;
01069
01070 Shape * clone() const;
01071
01072 private:
01073 static const std::string _name;
01075 protected:
01076 Color _color0;
01077 Color _color1;
01078 Color _color2;
01079 int _subdivisions;
01080 };
01081
01086 struct Ellipse : public Shape {
01087
01088 Ellipse( double x, double y,
01089 double xRadius, double yRadius,
01090 Color penColor, Color fillColor,
01091 float lineWidth, int depth = -1 )
01092 : Shape( penColor, fillColor, lineWidth, ButtCap, MiterJoin, depth ),
01093 _center( x, y ), _xRadius( xRadius ), _yRadius( yRadius ), _angle( 0.0 ),
01094 _circle( false ) {
01095 while ( _angle > M_PI_2 ) _angle -= M_PI;
01096 while ( _angle < -M_PI_2 ) _angle += M_PI;
01097 }
01098
01104 const std::string & name() const;
01105
01106 Point center() const;
01107
01108 Shape & rotate( double angle, const Point & center );
01109
01118 Ellipse rotated( double angle, const Point & center ) const;
01119
01120 Shape & rotate( double angle );
01121
01129 Ellipse rotated( double angle ) const;
01130
01131 Shape & translate( double dx, double dy );
01132
01141 Ellipse translated( double dx, double dy ) const;
01142
01143 Shape & scale( double sx, double sy );
01144
01145 Shape & scale( double s );
01146
01155 Ellipse scaled( double sx, double sy ) const;
01156
01157 Ellipse scaled( double s ) const;
01158
01165 void scaleAll( double s );
01166
01167 void flushPostscript( std::ostream & stream,
01168 const TransformEPS & transform ) const;
01169
01170 void flushFIG( std::ostream & stream,
01171 const TransformFIG & transform,
01172 std::map<Color,int> & colormap ) const;
01173
01174 void flushSVG( std::ostream & stream,
01175 const TransformSVG & transform ) const;
01176
01177 Rect boundingBox() const;
01178
01179 Shape * clone() const;
01180
01181 private:
01182 static const std::string _name;
01184 protected:
01185 Point _center;
01186 double _xRadius;
01187 double _yRadius;
01188 double _angle;
01189 bool _circle;
01190 };
01191
01196 struct Circle : public Ellipse {
01197
01198 Circle( double x, double y, double radius,
01199 Color penColor, Color fillColor,
01200 float lineWidth,
01201 int depth = -1 )
01202 : Ellipse( x, y, radius, radius, penColor, fillColor, lineWidth, depth )
01203 { _circle = true; }
01204
01210 const std::string & name() const;
01211
01212 Point center() const;
01213
01214 Shape & rotate( double angle, const Point & center );
01215
01216 Circle rotated( double angle, const Point & center ) const;
01217
01218 Shape & rotate( double angle );
01219
01220 Circle rotated( double angle ) const;
01221
01222 Shape & translate( double dx, double dy );
01223
01224 Circle translated( double dx, double dy ) const;
01225
01226 Shape & scale( double sx, double sy );
01227
01228 Shape & scale( double s );
01229
01230 Circle scaled( double sx, double sy ) const;
01231
01232 Circle scaled( double s ) const;
01233
01240 void scaleAll( double s );
01241
01242 void flushSVG( std::ostream & stream,
01243 const TransformSVG & transform ) const;
01244
01245 Shape * clone() const;
01246
01247 private:
01248 static const std::string _name;
01249 };
01250
01255 struct Text : public Shape {
01256
01270 Text( double x, double y,
01271 const std::string & text,
01272 const Fonts::Font font,
01273 float size,
01274 Color color = Color::Black,
01275 int depth = -1 )
01276 : Shape( color, Color::None, 1.0, ButtCap, MiterJoin, depth ),
01277 _position( x, y ), _text( text ), _font( font ),
01278 _angle( 0.0 ), _size( size ),
01279 _xScale( 1.0 ), _yScale( 1.0 ) { }
01280
01281
01296 Text( double x, double y,
01297 const std::string & text,
01298 const Fonts::Font font,
01299 const std::string & svgFont,
01300 float size,
01301 Color color = Color::Black,
01302 int depth = -1 )
01303 : Shape( color, Color::None, 1.0, ButtCap, MiterJoin, depth ),
01304 _position( x, y ),
01305 _text( text ), _font( font ), _svgFont( svgFont ),
01306 _angle( 0.0 ),
01307 _size( size ),
01308 _xScale( 1.0 ), _yScale( 1.0 ) { }
01309
01315 const std::string & name() const;
01316
01317 Point center() const;
01318
01319 Shape & rotate( double angle, const Point & center );
01320
01321 Text rotated( double angle, const Point & center ) const;
01322
01323 Shape & rotate( double angle );
01324
01325 Text rotated( double angle ) const;
01326
01327 Shape & translate( double dx, double dy );
01328
01329 Text translated( double dx, double dy ) const;
01330
01331 Shape & scale( double sx, double sy );
01332
01333 Shape & scale( double s );
01334
01335 Text scaled( double sx, double sy ) const;
01336
01337 Text scaled( double s ) const;
01338
01345 void scaleAll( double s );
01346
01347 void flushPostscript( std::ostream & stream,
01348 const TransformEPS & transform ) const;
01349
01350 void flushFIG( std::ostream & stream,
01351 const TransformFIG & transform,
01352 std::map<Color,int> & colormap ) const;
01353
01354 void flushSVG( std::ostream & stream,
01355 const TransformSVG & transform ) const;
01356
01357 Rect boundingBox() const;
01358
01359 Shape * clone() const;
01360
01361 private:
01362 static const std::string _name;
01364 protected:
01365 Point _position;
01366 std::string _text;
01367 Fonts::Font _font;
01368 std::string _svgFont;
01369 double _angle;
01370 float _size;
01371 double _xScale;
01372 double _yScale;
01373 };
01374
01383 bool shapeGreaterDepth( const Shape *s1, const Shape *s2 );
01384
01385 }
01386
01387
01388
01389 #endif
01390