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 "board/Tools.h"
00020 #include <string>
00021 #include <vector>
00022 #include <iostream>
00023 #include <map>
00024 #include <cmath>
00025
00026 #ifndef M_PI
00027 #define M_PI 3.14159265358979323846
00028 #endif
00029
00030 #ifndef M_PI_2
00031 #define M_PI_2 1.57079632679489661923
00032 #endif
00033
00034 namespace LibBoard {
00035
00040 struct Shape {
00041
00042 enum LineCap { ButtCap = 0, RoundCap, SquareCap };
00043 enum LineJoin { MiterJoin = 0, RoundJoin, BevelJoin };
00044 enum LineStyle { SolidStyle = 0,
00045 DashStyle,
00046 DotStyle,
00047 DashDotStyle,
00048 DashDotDotStyle,
00049 DashDotDotDotStyle };
00050
00059 inline Shape( Color penColor, Color fillColor,
00060 double lineWidth,
00061 LineStyle style,
00062 const LineCap cap,
00063 const LineJoin join,
00064 int depth );
00065
00069 virtual ~Shape() { }
00070
00076 virtual const std::string & name() const;
00077
00083 virtual Shape * clone() const = 0;
00084
00090 inline bool filled() const { return _fillColor != Color::None; }
00091
00097 virtual Point center() const = 0;
00098
00107 virtual Shape & rotate( double angle, const Point & center ) = 0;
00108
00116 virtual Shape & rotate( double angle ) = 0;
00117
00126 inline Shape & rotateDeg( double angle, const Point & center );
00127
00136 inline Shape & rotateDeg( double angle );
00137
00146 virtual Shape & translate( double dx, double dy ) = 0;
00147
00156 virtual Shape & scale( double sx, double sy ) = 0;
00157
00165 virtual Shape & scale( double s ) = 0;
00166
00172 virtual Rect boundingBox() const = 0;
00173
00174
00179 inline Rect bbox();
00180
00181
00187 inline Shape & operator--();
00188
00194 inline Shape & operator++();
00195
00196
00203 virtual void scaleAll( double s ) = 0;
00204
00205
00213 virtual void flushPostscript( std::ostream & stream,
00214 const TransformEPS & transform ) const = 0;
00215
00223 virtual void flushFIG( std::ostream & stream,
00224 const TransformFIG & transform,
00225 std::map<Color,int> & colormap ) const = 0;
00226
00234 virtual void flushSVG( std::ostream & stream,
00235 const TransformSVG & transform ) const = 0;
00236
00237 inline int depth() const;
00238
00239 virtual void depth( int );
00240
00241 virtual void shiftDepth( int shift );
00242
00243 inline const Color & penColor() const;
00244
00245 inline const Color & fillColor() const;
00246
00247 private:
00248 static const std::string _name;
00250 protected:
00251
00252 int _depth;
00253 Color _penColor;
00254 Color _fillColor;
00255 double _lineWidth;
00256 LineStyle _lineStyle;
00257 LineCap _lineCap;
00258 LineJoin _lineJoin;
00266 std::string svgProperties( const TransformSVG & transform ) const;
00267
00268
00274 std::string postscriptProperties() const;
00275
00276 };
00277
00278
00279 inline Rect
00280 Shape::bbox()
00281 {
00282 return this->boundingBox();
00283 }
00284
00285
00286 inline Shape &
00287 Shape::operator++()
00288 {
00289 ++_depth;
00290 return *this;
00291 }
00292
00293 inline Shape &
00294 Shape::operator--()
00295 {
00296 --_depth;
00297 return *this;
00298 }
00299
00300
00301 inline int
00302 Shape::depth() const
00303 {
00304 return _depth;
00305 }
00306
00307 inline const Color &
00308 Shape::penColor() const
00309 {
00310 return _penColor;
00311 }
00312
00313 const Color &
00314 Shape::fillColor() const
00315 {
00316 return _fillColor;
00317 }
00318
00319 Shape &
00320 Shape::rotateDeg( double angle, const Point & center )
00321 {
00322 return rotate( angle * ( M_PI / 180.0 ), center );
00323 }
00324
00325 Shape &
00326 Shape::rotateDeg( double angle )
00327 {
00328 return rotate( angle * ( M_PI / 180.0 ), center() );
00329 }
00330
00339 struct Dot : public Shape {
00340
00341 inline Dot( double x, double y,
00342 Color color,
00343 double lineWidth,
00344 int depth = -1 );
00345
00351 const std::string & name() const;
00352
00353 Point center() const;
00354
00363 Dot & rotate( double angle, const Point & center );
00364
00373 Dot rotated( double angle, const Point & center ) const;
00374
00382 Dot & rotate( double angle );
00383
00391 Dot rotated( double angle ) const;
00392
00401 Dot & translate( double dx, double dy );
00402
00411 Dot translated( double dx, double dy ) const;
00412
00413 Shape & scale( double sx, double sy );
00414
00415 Shape & scale( double s );
00416
00427 Dot scaled( double sx, double sy ) const;
00428
00429 Dot scaled( double s ) const;
00430
00437 void scaleAll( double s );
00438
00439 void flushPostscript( std::ostream & stream,
00440 const TransformEPS & transform ) const;
00441
00442 void flushFIG( std::ostream & stream,
00443 const TransformFIG & transform,
00444 std::map<Color,int> & colormap ) const;
00445
00446 void flushSVG( std::ostream & stream,
00447 const TransformSVG & transform ) const;
00448
00449 Rect boundingBox() const;
00450
00451 Dot * clone() const;
00452
00453 private:
00454 static const std::string _name;
00456 protected:
00457 double _x;
00458 double _y;
00459 };
00460
00465 struct Line : public Shape {
00466
00478 inline Line( double x1, double y1, double x2, double y2,
00479 Color color,
00480 double lineWidth,
00481 const LineStyle style = SolidStyle,
00482 const LineCap cap = ButtCap,
00483 const LineJoin join = MiterJoin,
00484 int depth = -1 );
00485
00491 const std::string & name() const;
00492
00493 Point center() const;
00494
00495 Line & rotate( double angle, const Point & center );
00496
00505 Line rotated( double angle, const Point & center ) const;
00506
00507 Line & rotate( double angle );
00508
00516 Line rotated( double angle ) const;
00517
00518 Line & translate( double dx, double dy );
00519
00528 Line translated( double dx, double dy ) const;
00529
00530 Shape & scale( double sx, double sy );
00531
00532 Shape & scale( double s );
00533
00542 Line scaled( double sx, double sy ) const;
00543
00544 Line scaled( double s ) const;
00545
00552 void scaleAll( double s );
00553
00554 void flushPostscript( std::ostream & stream,
00555 const TransformEPS & transform ) const;
00556
00557 void flushFIG( std::ostream & stream,
00558 const TransformFIG & transform,
00559 std::map<Color,int> & colormap ) const;
00560
00561 void flushSVG( std::ostream & stream,
00562 const TransformSVG & transform ) const;
00563
00564 Rect boundingBox() const;
00565
00566 Line * clone() const;
00567
00568 private:
00569 static const std::string _name;
00571 protected:
00572 double _x1;
00573 double _y1;
00574 double _x2;
00575 double _y2;
00576 };
00577
00582 struct Arrow : public Line {
00583
00596 inline Arrow( double x1, double y1, double x2, double y2,
00597 Color penColor, Color fillColor,
00598 double lineWidth,
00599 const LineStyle style = SolidStyle,
00600 const LineCap cap = ButtCap,
00601 const LineJoin join = MiterJoin,
00602 int depth = -1 );
00603
00609 const std::string & name() const;
00610
00619 Arrow rotated( double angle, const Point & center ) const;
00620
00628 Arrow rotated( double angle ) const;
00629
00638 Arrow translated( double dx, double dy ) const;
00639
00648 Arrow scaled( double sx, double sy ) const;
00649
00650 Arrow scaled( double s ) const;
00651
00652 void flushPostscript( std::ostream & stream,
00653 const TransformEPS & transform ) const;
00654
00655 void flushFIG( std::ostream & stream,
00656 const TransformFIG & transform,
00657 std::map<Color,int> & colormap ) const;
00658 void flushSVG( std::ostream & stream,
00659 const TransformSVG & transform ) const;
00660
00661 Arrow * clone() const;
00662
00663 private:
00664 static const std::string _name;
00665 };
00666
00671 struct Polyline : public Shape {
00672 inline Polyline( const std::vector<Point> & points,
00673 bool closed,
00674 Color penColor, Color fillColor,
00675 double lineWidth,
00676 const LineStyle lineStyle = SolidStyle,
00677 const LineCap cap = ButtCap,
00678 const LineJoin join = MiterJoin,
00679 int depth = -1 );
00680
00681 inline Polyline( const Path & path,
00682 Color penColor, Color fillColor,
00683 double lineWidth,
00684 const LineStyle lineStyle = SolidStyle,
00685 const LineCap cap = ButtCap,
00686 const LineJoin join = MiterJoin,
00687 int depth = -1 );
00688
00689 inline Polyline( bool closed, Color penColor, Color fillColor,
00690 double lineWidth,
00691 const LineStyle lineStyle = SolidStyle,
00692 const LineCap cap = ButtCap,
00693 const LineJoin join = MiterJoin,
00694 int depth = -1 );
00695
00701 const std::string & name() const;
00702
00703 Point center() const;
00704
00712 Polyline & operator<<( const Point & p );
00713
00721 Point & operator[]( const unsigned int n ) {
00722 return _path[ n ];
00723 }
00724
00725
00726 Polyline & rotate( double angle, const Point & center );
00727
00736 Polyline rotated( double angle, const Point & center ) const;
00737
00738 Polyline & rotate( double angle );
00739
00747 Polyline rotated( double angle ) const;
00748
00749 Polyline & translate( double dx, double dy );
00750
00759 Polyline translated( double dx, double dy ) const;
00760
00761 Shape & scale( double sx, double sy );
00762
00763 Shape & scale( double s );
00764
00773 Polyline scaled( double sx, double sy ) const;
00774
00775 Polyline scaled( double s ) const;
00776
00783 void scaleAll( double s );
00784
00785 void flushPostscript( std::ostream & stream,
00786 const TransformEPS & transform ) const;
00787
00788 void flushFIG( std::ostream & stream,
00789 const TransformFIG & transform,
00790 std::map<Color,int> & colormap ) const;
00791
00792 void flushSVG( std::ostream & stream,
00793 const TransformSVG & transform ) const;
00794
00795 Rect boundingBox() const;
00796
00797 Polyline * clone() const;
00798
00799 private:
00800 static const std::string _name;
00802 protected:
00803 Path _path;
00804 };
00805
00810 struct Rectangle : public Polyline {
00811
00812 inline Rectangle( double x, double y, double width, double height,
00813 Color penColor, Color fillColor,
00814 double lineWidth,
00815 const LineStyle style = SolidStyle,
00816 const LineCap cap = ButtCap,
00817 const LineJoin join = MiterJoin,
00818 int depth = -1 );
00819
00820 inline Rectangle( const Rect & rect,
00821 Color penColor, Color fillColor,
00822 double lineWidth,
00823 const LineStyle style = SolidStyle,
00824 const LineCap cap = ButtCap,
00825 const LineJoin join = MiterJoin,
00826 int depth = -1 );
00827
00833 const std::string & name() const;
00834
00835 double x() const { return _path[0].x; }
00836 double y() const { return _path[0].y; }
00837 double width() { return (_path[1] - _path[0]).norm(); }
00838 double height() { return (_path[0] - _path[3]).norm(); }
00839 Point topLeft() { return Point( _path[0].x, _path[0].y ); }
00840 Point topRight() { return Point( _path[1].x, _path[1].y ); }
00841 Point bottomLeft() { return Point( _path[3].x, _path[3].y ); }
00842 Point bottomRight() { return Point( _path[2].x, _path[2].y ); }
00843
00844
00853 Rectangle rotated( double angle, const Point & center ) const;
00854
00862 Rectangle rotated( double angle ) const;
00863
00872 Rectangle translated( double dx, double dy ) const;
00873
00882 Rectangle scaled( double sx, double sy ) const;
00883
00884 Rectangle scaled( double s ) const;
00885
00892 void scaleAll( double s );
00893
00894 void flushFIG( std::ostream & stream,
00895 const TransformFIG & transform,
00896 std::map<Color,int> & colormap ) const;
00897
00898 void flushSVG( std::ostream & stream,
00899 const TransformSVG & transform ) const;
00900
00901 Rectangle * clone() const;
00902
00903 private:
00904 static const std::string _name;
00906 protected:
00907 bool _isRectangle;
00908 };
00909
00910
00915 struct Triangle : public Polyline {
00916
00917 Triangle( const Point & p1, const Point & p2, const Point & p3,
00918 Color penColor, Color fillColor,
00919 double lineWidth,
00920 const LineStyle style = SolidStyle,
00921 const LineCap cap = ButtCap,
00922 const LineJoin join = MiterJoin,
00923 int depth = -1 )
00924 : Polyline( std::vector<Point>(), true, penColor, fillColor, lineWidth, style, cap, join, depth ) {
00925 _path << p1;
00926 _path << p2;
00927 _path << p3;
00928 }
00929
00930 Triangle( const double x1, const double y1,
00931 const double x2, const double y2,
00932 const double x3, const double y3,
00933 Color penColor, Color fillColor,
00934 double lineWidth,
00935 const LineStyle style = SolidStyle,
00936 const LineCap cap = ButtCap,
00937 const LineJoin join = MiterJoin,
00938 int depth = -1 )
00939 : Polyline( std::vector<Point>(), true, penColor, fillColor, lineWidth, style, cap, join, depth ) {
00940 _path << Point( x1, y1 );
00941 _path << Point( x2, y2 );
00942 _path << Point( x3, y3 );
00943 }
00944
00950 const std::string & name() const;
00951
00952 Triangle rotated( double angle ) const;
00953
00962 Triangle translated( double dx, double dy ) const;
00963
00972 Triangle scaled( double sx, double sy ) const;
00973
00974 Triangle scaled( double s ) const;
00975
00976 Triangle * clone() const;
00977
00978 private:
00979 static const std::string _name;
00981 protected:
00982 };
00983
00984
00989 struct GouraudTriangle : public Polyline {
00990
00991
00992 GouraudTriangle( const Point & p0, const Color & color0,
00993 const Point & p1, const Color & color1,
00994 const Point & p2, const Color & color2,
00995 int subdivisions,
00996 int depth = -1 );
00997
00998 GouraudTriangle( const Point & p0, float brightness0,
00999 const Point & p1, float brightness1,
01000 const Point & p2, float brightness2,
01001 const Color & fillColor,
01002 int subdivisions,
01003 int depth = -1 );
01004
01010 const std::string & name() const;
01011
01012 Point center() const;
01013
01014 GouraudTriangle & rotate( double angle, const Point & center );
01015
01016 GouraudTriangle rotated( double angle, const Point & center ) const;
01017
01018 GouraudTriangle & rotate( double angle );
01019
01020 GouraudTriangle rotated( double angle ) const;
01021
01030 GouraudTriangle translated( double dx, double dy ) const;
01031
01040 GouraudTriangle scaled( double sx, double sy ) const;
01041
01042 GouraudTriangle scaled( double s ) const;
01043
01044
01051 void scaleAll( double s );
01052
01059 void flushPostscript( std::ostream & stream,
01060 const TransformEPS & transform ) const;
01061
01074 void flushFIG( std::ostream & stream,
01075 const TransformFIG & transform,
01076 std::map<Color,int> & colormap ) const;
01077
01078 void flushSVG( std::ostream & stream,
01079 const TransformSVG & transform ) const;
01080
01081 GouraudTriangle * clone() const;
01082
01083 private:
01084 static const std::string _name;
01086 protected:
01087 Color _color0;
01088 Color _color1;
01089 Color _color2;
01090 int _subdivisions;
01091 };
01092
01097 struct Ellipse : public Shape {
01098
01099 Ellipse( double x, double y,
01100 double xRadius, double yRadius,
01101 Color penColor, Color fillColor,
01102 double lineWidth,
01103 const LineStyle lineStyle = SolidStyle,
01104 int depth = -1 )
01105 : Shape( penColor, fillColor,
01106 lineWidth, lineStyle, ButtCap, MiterJoin, depth ),
01107 _center( x, y ), _xRadius( xRadius ), _yRadius( yRadius ),
01108 _angle( 0.0 ),
01109 _circle( false ) {
01110 while ( _angle > M_PI_2 ) _angle -= M_PI;
01111 while ( _angle < -M_PI_2 ) _angle += M_PI;
01112 }
01113
01119 const std::string & name() const;
01120
01121 Point center() const;
01122
01123 Ellipse & rotate( double angle, const Point & center );
01124
01133 Ellipse rotated( double angle, const Point & center ) const;
01134
01135 Ellipse & rotate( double angle );
01136
01144 Ellipse rotated( double angle ) const;
01145
01146 Ellipse & translate( double dx, double dy );
01147
01156 Ellipse translated( double dx, double dy ) const;
01157
01158 Shape & scale( double sx, double sy );
01159
01160 Shape & scale( double s );
01161
01170 Ellipse scaled( double sx, double sy ) const;
01171
01172 Ellipse scaled( double s ) const;
01173
01180 void scaleAll( double s );
01181
01182 void flushPostscript( std::ostream & stream,
01183 const TransformEPS & transform ) const;
01184
01185 void flushFIG( std::ostream & stream,
01186 const TransformFIG & transform,
01187 std::map<Color,int> & colormap ) const;
01188
01189 void flushSVG( std::ostream & stream,
01190 const TransformSVG & transform ) const;
01191
01192 Rect boundingBox() const;
01193
01194 Ellipse * clone() const;
01195
01196 private:
01197 static const std::string _name;
01199 protected:
01200 Point _center;
01201 double _xRadius;
01202 double _yRadius;
01203 double _angle;
01204 bool _circle;
01205 };
01206
01211 struct Circle : public Ellipse {
01212
01213 Circle( double x, double y, double radius,
01214 Color penColor, Color fillColor,
01215 double lineWidth,
01216 const LineStyle style = SolidStyle,
01217 int depth = -1 )
01218 : Ellipse( x, y, radius, radius, penColor, fillColor, lineWidth, style, depth )
01219 { _circle = true; }
01220
01226 const std::string & name() const;
01227
01228 Point center() const;
01229
01230 Circle & rotate( double angle, const Point & center );
01231
01232 Circle rotated( double angle, const Point & center ) const;
01233
01234 Circle & rotate( double angle );
01235
01236 Circle rotated( double angle ) const;
01237
01238 Circle & translate( double dx, double dy );
01239
01240 Circle translated( double dx, double dy ) const;
01241
01242 Shape & scale( double sx, double sy );
01243
01244 Shape & scale( double s );
01245
01246 Circle scaled( double sx, double sy ) const;
01247
01248 Circle scaled( double s ) const;
01249
01256 void scaleAll( double s );
01257
01258 void flushSVG( std::ostream & stream,
01259 const TransformSVG & transform ) const;
01260
01261 Circle * clone() const;
01262
01263 private:
01264 static const std::string _name;
01265 };
01266
01271 struct Text : public Shape {
01272
01286 Text( double x, double y,
01287 const std::string & text,
01288 const Fonts::Font font,
01289 double size,
01290 Color color = Color::Black,
01291 int depth = -1 )
01292 : Shape( color, Color::None, 1.0, SolidStyle, ButtCap, MiterJoin, depth ),
01293 _position( x, y ), _text( text ), _font( font ),
01294 _angle( 0.0 ), _size( size ),
01295 _xScale( 1.0 ), _yScale( 1.0 ) { }
01296
01297
01312 Text( double x, double y,
01313 const std::string & text,
01314 const Fonts::Font font,
01315 const std::string & svgFont,
01316 double size,
01317 Color color = Color::Black,
01318 int depth = -1 )
01319 : Shape( color, Color::None, 1.0, SolidStyle, ButtCap, MiterJoin, depth ),
01320 _position( x, y ),
01321 _text( text ), _font( font ), _svgFont( svgFont ),
01322 _angle( 0.0 ),
01323 _size( size ),
01324 _xScale( 1.0 ), _yScale( 1.0 ) { }
01325
01331 const std::string & name() const;
01332
01333 Point center() const;
01334
01335 Text & rotate( double angle, const Point & center );
01336
01337 Text rotated( double angle, const Point & center ) const;
01338
01339 Text & rotate( double angle );
01340
01341 Text rotated( double angle ) const;
01342
01343 Text & translate( double dx, double dy );
01344
01345 Text translated( double dx, double dy ) const;
01346
01347 Shape & scale( double sx, double sy );
01348
01349 Shape & scale( double s );
01350
01351 Text scaled( double sx, double sy ) const;
01352
01353 Text scaled( double s ) const;
01354
01361 void scaleAll( double s );
01362
01363 void flushPostscript( std::ostream & stream,
01364 const TransformEPS & transform ) const;
01365
01366 void flushFIG( std::ostream & stream,
01367 const TransformFIG & transform,
01368 std::map<Color,int> & colormap ) const;
01369
01370 void flushSVG( std::ostream & stream,
01371 const TransformSVG & transform ) const;
01372
01373 Rect boundingBox() const;
01374
01375 Text * clone() const;
01376
01377 private:
01378 static const std::string _name;
01380 protected:
01381 Point _position;
01382 std::string _text;
01383 Fonts::Font _font;
01384 std::string _svgFont;
01385 double _angle;
01386 double _size;
01387 double _xScale;
01388 double _yScale;
01389 };
01390
01399 bool shapeGreaterDepth( const Shape *s1, const Shape *s2 );
01400
01401
01402 }
01403
01404
01405
01406
01407 #include "Shapes.ih"
01408
01409
01410 #endif
01411