1 /*
2  * Copyright (C) 2003, 2006, 2009 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #ifndef IntRect_h
27 #define IntRect_h
28 
29 #include "IntPoint.h"
30 #include <wtf/Vector.h>
31 
32 #if USE(CG) || USE(SKIA_ON_MAC_CHROME)
33 typedef struct CGRect CGRect;
34 #endif
35 
36 #if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) || (PLATFORM(QT) && USE(QTKIT))
37 #ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES
38 typedef struct CGRect NSRect;
39 #else
40 typedef struct _NSRect NSRect;
41 #endif
42 #endif
43 
44 #if PLATFORM(WIN)
45 typedef struct tagRECT RECT;
46 #elif PLATFORM(QT)
47 QT_BEGIN_NAMESPACE
48 class QRect;
49 QT_END_NAMESPACE
50 #elif PLATFORM(GTK)
51 #ifdef GTK_API_VERSION_2
52 typedef struct _GdkRectangle GdkRectangle;
53 #else
54 typedef struct _cairo_rectangle_int cairo_rectangle_int_t;
55 typedef cairo_rectangle_int_t GdkRectangle;
56 #endif
57 #elif PLATFORM(HAIKU)
58 class BRect;
59 #elif PLATFORM(EFL)
60 typedef struct _Eina_Rectangle Eina_Rectangle;
61 #endif
62 
63 #if PLATFORM(WX)
64 class wxRect;
65 #endif
66 
67 #if USE(SKIA)
68 struct SkRect;
69 struct SkIRect;
70 #endif
71 
72 namespace WebCore {
73 
74 class FloatRect;
75 
76 class IntRect {
77 public:
IntRect()78     IntRect() { }
IntRect(const IntPoint & location,const IntSize & size)79     IntRect(const IntPoint& location, const IntSize& size)
80         : m_location(location), m_size(size) { }
IntRect(int x,int y,int width,int height)81     IntRect(int x, int y, int width, int height)
82         : m_location(IntPoint(x, y)), m_size(IntSize(width, height)) { }
83 
84     explicit IntRect(const FloatRect& rect); // don't do this implicitly since it's lossy
85 
location()86     IntPoint location() const { return m_location; }
size()87     IntSize size() const { return m_size; }
88 
setLocation(const IntPoint & location)89     void setLocation(const IntPoint& location) { m_location = location; }
setSize(const IntSize & size)90     void setSize(const IntSize& size) { m_size = size; }
91 
x()92     int x() const { return m_location.x(); }
y()93     int y() const { return m_location.y(); }
maxX()94     int maxX() const { return x() + width(); }
maxY()95     int maxY() const { return y() + height(); }
width()96     int width() const { return m_size.width(); }
height()97     int height() const { return m_size.height(); }
98 
setX(int x)99     void setX(int x) { m_location.setX(x); }
setY(int y)100     void setY(int y) { m_location.setY(y); }
setWidth(int width)101     void setWidth(int width) { m_size.setWidth(width); }
setHeight(int height)102     void setHeight(int height) { m_size.setHeight(height); }
103 
isEmpty()104     bool isEmpty() const { return m_size.isEmpty(); }
105 
106     // NOTE: The result is rounded to integer values, and thus may be not the exact
107     // center point.
center()108     IntPoint center() const { return IntPoint(x() + width() / 2, y() + height() / 2); }
109 
move(const IntSize & s)110     void move(const IntSize& s) { m_location += s; }
move(int dx,int dy)111     void move(int dx, int dy) { m_location.move(dx, dy); }
112 
shiftXEdgeTo(int edge)113     void shiftXEdgeTo(int edge)
114     {
115         int delta = edge - x();
116         setX(edge);
117         setWidth(std::max(0, width() - delta));
118     }
shiftMaxXEdgeTo(int edge)119     void shiftMaxXEdgeTo(int edge)
120     {
121         int delta = edge - maxX();
122         setWidth(std::max(0, width() + delta));
123     }
shiftYEdgeTo(int edge)124     void shiftYEdgeTo(int edge)
125     {
126         int delta = edge - y();
127         setY(edge);
128         setHeight(std::max(0, height() - delta));
129     }
shiftMaxYEdgeTo(int edge)130     void shiftMaxYEdgeTo(int edge)
131     {
132         int delta = edge - maxY();
133         setHeight(std::max(0, height() + delta));
134     }
135 
minXMinYCorner()136     IntPoint minXMinYCorner() const { return m_location; } // typically topLeft
maxXMinYCorner()137     IntPoint maxXMinYCorner() const { return IntPoint(m_location.x() + m_size.width(), m_location.y()); } // typically topRight
minXMaxYCorner()138     IntPoint minXMaxYCorner() const { return IntPoint(m_location.x(), m_location.y() + m_size.height()); } // typically bottomLeft
maxXMaxYCorner()139     IntPoint maxXMaxYCorner() const { return IntPoint(m_location.x() + m_size.width(), m_location.y() + m_size.height()); } // typically bottomRight
140 
141     bool intersects(const IntRect&) const;
142     bool contains(const IntRect&) const;
143 
144     // This checks to see if the rect contains x,y in the traditional sense.
145     // Equivalent to checking if the rect contains a 1x1 rect below and to the right of (px,py).
contains(int px,int py)146     bool contains(int px, int py) const
147         { return px >= x() && px < maxX() && py >= y() && py < maxY(); }
contains(const IntPoint & point)148     bool contains(const IntPoint& point) const { return contains(point.x(), point.y()); }
149 
150     void intersect(const IntRect&);
151     void unite(const IntRect&);
152     void uniteIfNonZero(const IntRect&);
153 
inflateX(int dx)154     void inflateX(int dx)
155     {
156         m_location.setX(m_location.x() - dx);
157         m_size.setWidth(m_size.width() + dx + dx);
158     }
inflateY(int dy)159     void inflateY(int dy)
160     {
161         m_location.setY(m_location.y() - dy);
162         m_size.setHeight(m_size.height() + dy + dy);
163     }
inflate(int d)164     void inflate(int d) { inflateX(d); inflateY(d); }
165     void scale(float s);
166 
transposedRect()167     IntRect transposedRect() const { return IntRect(m_location.transposedPoint(), m_size.transposedSize()); }
168 
169 #if PLATFORM(WX)
170     IntRect(const wxRect&);
171     operator wxRect() const;
172 #endif
173 
174 #if PLATFORM(WIN)
175     IntRect(const RECT&);
176     operator RECT() const;
177 #elif PLATFORM(QT)
178     IntRect(const QRect&);
179     operator QRect() const;
180 #elif PLATFORM(GTK)
181     IntRect(const GdkRectangle&);
182     operator GdkRectangle() const;
183 #elif PLATFORM(HAIKU)
184     explicit IntRect(const BRect&);
185     operator BRect() const;
186 #elif PLATFORM(EFL)
187     explicit IntRect(const Eina_Rectangle&);
188     operator Eina_Rectangle() const;
189 #endif
190 
191 #if USE(CG) || USE(SKIA_ON_MAC_CHROME)
192     operator CGRect() const;
193 #endif
194 
195 #if USE(SKIA)
196     IntRect(const SkIRect&);
197     operator SkRect() const;
198     operator SkIRect() const;
199 #endif
200 
201 #if (PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)) \
202         || (PLATFORM(CHROMIUM) && OS(DARWIN))  || (PLATFORM(QT) && USE(QTKIT))
203     operator NSRect() const;
204 #endif
205 
206 private:
207     IntPoint m_location;
208     IntSize m_size;
209 };
210 
intersection(const IntRect & a,const IntRect & b)211 inline IntRect intersection(const IntRect& a, const IntRect& b)
212 {
213     IntRect c = a;
214     c.intersect(b);
215     return c;
216 }
217 
unionRect(const IntRect & a,const IntRect & b)218 inline IntRect unionRect(const IntRect& a, const IntRect& b)
219 {
220     IntRect c = a;
221     c.unite(b);
222     return c;
223 }
224 
225 IntRect unionRect(const Vector<IntRect>&);
226 
227 inline bool operator==(const IntRect& a, const IntRect& b)
228 {
229     return a.location() == b.location() && a.size() == b.size();
230 }
231 
232 inline bool operator!=(const IntRect& a, const IntRect& b)
233 {
234     return a.location() != b.location() || a.size() != b.size();
235 }
236 
237 #if USE(CG) || USE(SKIA_ON_MAC_CHROME)
238 IntRect enclosingIntRect(const CGRect&);
239 #endif
240 
241 #if (PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)) \
242         || (PLATFORM(CHROMIUM) && OS(DARWIN)) || (PLATFORM(QT) && USE(QTKIT))
243 IntRect enclosingIntRect(const NSRect&);
244 #endif
245 
246 } // namespace WebCore
247 
248 #endif // IntRect_h
249