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