Fix bugs in previous commit that caused FTBFS in synfig and ETL FTBFS with older...
[synfig.git] / synfig-core / tags / synfig_0_61_03 / synfig-core / src / synfig / rect.h
1 /* === S Y N F I G ========================================================= */
2 /*!     \file rect.h
3 **      \brief Rectangle Class
4 **
5 **      $Id: rect.h,v 1.1.1.1 2005/01/04 01:23:14 darco Exp $
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 zero()
55         {
56                 return Rect(
57                         0,
58                         0,
59                         0,
60                         0
61                 );
62         }
63
64         Rect() { }
65
66         Rect(const Point& x) { set_point(x); }
67
68         Rect(const Point& min, const Point& max) { set_point(min); expand(max); }
69
70         Rect(const value_type &x1,const value_type &y1) { set_point(x1,y1); }
71         
72         Rect(const value_type &x1,const value_type &y1,
73                         const value_type &x2,const value_type &y2)
74         {
75                 set_point(x1,y1);
76                 expand(x2,y2);
77         }
78                 
79         void set_point(const Point& max) { set_point(max[0],max[1]);    }
80         
81         Rect& expand(const Point& max) { expand(max[0],max[1]); return *this; }
82
83         Rect& expand(const Real& r) { minx-=r; miny-=r; maxx+=r; maxy+=r; return *this; }
84
85         Rect& expand_x(const Real& r) { minx-=r; maxx+=r; return *this; }
86
87         Rect& expand_y(const Real& r) { miny-=r; maxy+=r; return *this; }
88         
89         Rect& set(const Point& min,const Point& max) { set(min[0],min[1],max[0],max[1]); return *this; }
90         
91         Point get_min()const { return Point(minx,miny); }
92         Point get_max()const { return Point(maxx,maxy); }
93         
94         bool is_inside(const Point& x) { return x[0]>minx && x[0]<maxx && x[1]>miny && x[1]<maxy; }
95                 
96         Real area()const
97         {
98                 return (maxx-minx)*(maxy-miny);
99         }
100         
101         // Operators
102         
103         Rect& operator+=(const Vector& rhs)
104         {
105                 minx+=rhs[0]; miny+=rhs[1];
106                 maxx+=rhs[0]; maxy+=rhs[1];
107                 return *this;
108         }
109
110         Rect& operator-=(const Vector& rhs)
111         {
112                 minx-=rhs[0]; miny-=rhs[1];
113                 maxx-=rhs[0]; maxy-=rhs[1];
114                 return *this;
115         }
116
117         Rect& operator*=(const Real& rhs)
118         {
119                 minx*=rhs; miny*=rhs;
120                 maxx*=rhs; maxy*=rhs;
121                 return *this;
122         }
123
124         Rect& operator/=(Real rhs)
125         {
126                 rhs=1.0/rhs; // Avoid doing several divisions
127                 minx*=rhs; miny*=rhs;
128                 maxx*=rhs; maxy*=rhs;
129                 return *this;
130         }
131
132         Rect& operator&=(const Rect& rhs)
133         {
134                 if(rhs.area()>0.00000001 && area()>0.00000001)
135                         etl::set_intersect(*this,*this,rhs);
136                 else
137                         *this=zero();
138                 return *this;
139         }
140
141         Rect& operator|=(const Rect& rhs)
142         {
143                 if(rhs.area()>0.00000001 && area()>0.00000001)
144                         etl::set_union(*this,*this,rhs);
145                 else
146                 {
147                         if(area()<rhs.area())
148                                 *this=rhs;
149                 }
150                 return *this;
151         }
152
153         Rect operator+(const Vector& rhs)const { return Rect(*this)+=rhs; }
154
155         Rect operator-(const Vector& rhs)const { return Rect(*this)-=rhs; }
156
157         Rect operator*(const Real& rhs)const { return Rect(*this)*=rhs; }
158
159         Rect operator/(const Real& rhs)const { return Rect(*this)/=rhs; }
160
161         Rect operator&(const Rect& rhs)const { return Rect(*this)&=rhs; }
162
163         Rect operator|(const Rect& rhs)const { return Rect(*this)|=rhs; }
164
165         bool operator&&(const Rect& rhs)const { return etl::intersect(*this, rhs); }
166
167         bool is_valid()const { return valid(); }
168 }; // END of class Rect
169
170 }; // END of namespace synfig
171
172 /* === E N D =============================================================== */
173
174 #endif