Add Rect::horizontal_strip() and Rect::vertical_strip() to create infinite slices...
[synfig.git] / synfig-core / trunk / src / synfig / rect.h
1 /* === S Y N F I G ========================================================= */
2 /*!     \file rect.h
3 **      \brief Rectangle Class
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **
10 **      This package is free software; you can redistribute it and/or
11 **      modify it under the terms of the GNU General Public License as
12 **      published by the Free Software Foundation; either version 2 of
13 **      the License, or (at your option) any later version.
14 **
15 **      This package is distributed in the hope that it will be useful,
16 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
17 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 **      General Public License for more details.
19 **      \endlegal
20 */
21 /* ========================================================================= */
22
23 /* === S T A R T =========================================================== */
24
25 #ifndef __SYNFIG_RECT_H
26 #define __SYNFIG_RECT_H
27
28 /* === H E A D E R S ======================================================= */
29
30 #include <ETL/rect>
31 #include "real.h"
32 #include "vector.h"
33 #include <limits>
34 #include <cmath>
35
36 /* === M A C R O S ========================================================= */
37
38 /* === T Y P E D E F S ===================================================== */
39
40 /* === C L A S S E S & S T R U C T S ======================================= */
41
42 namespace synfig {
43
44 class Rect : public etl::rect<Real>
45 {
46 public:
47
48         using etl::rect<Real>::set_point;
49         using etl::rect<Real>::expand;
50         using etl::rect<Real>::set;
51
52         static Rect full_plane();
53
54         static Rect horizontal_strip(const value_type &y1, const value_type &y2);
55         static Rect vertical_strip(const value_type &x1, const value_type &x2);
56
57         static Rect zero()
58         {
59                 return Rect(
60                         0,
61                         0,
62                         0,
63                         0
64                 );
65         }
66
67         Rect() { }
68
69         Rect(const Point& x) { set_point(x); }
70
71         Rect(const Point& min, const Point& max) { set_point(min); expand(max); }
72
73         Rect(const value_type &x1,const value_type &y1) { set_point(x1,y1); }
74
75         Rect(const value_type &x1,const value_type &y1,
76                         const value_type &x2,const value_type &y2)
77         {
78                 set_point(x1,y1);
79                 expand(x2,y2);
80         }
81
82         void set_point(const Point& max) { set_point(max[0],max[1]);    }
83
84         Rect& expand(const Point& max) { expand(max[0],max[1]); return *this; }
85
86         Rect& expand(const Real& r) { minx-=r; miny-=r; maxx+=r; maxy+=r; return *this; }
87
88         Rect& expand_x(const Real& r) { minx-=r; maxx+=r; return *this; }
89
90         Rect& expand_y(const Real& r) { miny-=r; maxy+=r; return *this; }
91
92         Rect& set(const Point& min,const Point& max) { set(min[0],min[1],max[0],max[1]); return *this; }
93
94         Point get_min()const { return Point(minx,miny); }
95         Point get_max()const { return Point(maxx,maxy); }
96
97         bool is_inside(const Point& x) { return x[0]>minx && x[0]<maxx && x[1]>miny && x[1]<maxy; }
98
99         Real area()const
100         {
101                 return (maxx-minx)*(maxy-miny);
102         }
103
104         // Operators
105
106         Rect& operator+=(const Vector& rhs)
107         {
108                 minx+=rhs[0]; miny+=rhs[1];
109                 maxx+=rhs[0]; maxy+=rhs[1];
110                 return *this;
111         }
112
113         Rect& operator-=(const Vector& rhs)
114         {
115                 minx-=rhs[0]; miny-=rhs[1];
116                 maxx-=rhs[0]; maxy-=rhs[1];
117                 return *this;
118         }
119
120         Rect& operator*=(const Real& rhs)
121         {
122                 minx*=rhs; miny*=rhs;
123                 maxx*=rhs; maxy*=rhs;
124                 return *this;
125         }
126
127         Rect& operator/=(Real rhs)
128         {
129                 rhs=1.0/rhs; // Avoid doing several divisions
130                 minx*=rhs; miny*=rhs;
131                 maxx*=rhs; maxy*=rhs;
132                 return *this;
133         }
134
135         Rect& operator&=(const Rect& rhs)
136         {
137                 if(rhs.area()>0.00000001 && area()>0.00000001)
138                         etl::set_intersect(*this,*this,rhs);
139                 else
140                         *this=zero();
141                 return *this;
142         }
143
144         Rect& operator|=(const Rect& rhs)
145         {
146                 if(rhs.area()>0.00000001 && area()>0.00000001)
147                         etl::set_union(*this,*this,rhs);
148                 else
149                 {
150                         if(area()<rhs.area())
151                                 *this=rhs;
152                 }
153                 return *this;
154         }
155
156         Rect operator+(const Vector& rhs)const { return Rect(*this)+=rhs; }
157
158         Rect operator-(const Vector& rhs)const { return Rect(*this)-=rhs; }
159
160         Rect operator*(const Real& rhs)const { return Rect(*this)*=rhs; }
161
162         Rect operator/(const Real& rhs)const { return Rect(*this)/=rhs; }
163
164         Rect operator&(const Rect& rhs)const { return Rect(*this)&=rhs; }
165
166         Rect operator|(const Rect& rhs)const { return Rect(*this)|=rhs; }
167
168         bool operator&&(const Rect& rhs)const { return etl::intersect(*this, rhs); }
169
170         bool is_valid()const { return valid(); }
171 }; // END of class Rect
172
173 }; // END of namespace synfig
174
175 /* === E N D =============================================================== */
176
177 #endif