Select best target for tap gesture.
[WebKit-https.git] / Source / WebCore / platform / graphics / IntRect.h
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_CHROMIUM)
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 #endif
54 #elif PLATFORM(EFL)
55 typedef struct _Eina_Rectangle Eina_Rectangle;
56 #elif PLATFORM(BLACKBERRY)
57 namespace BlackBerry {
58 namespace Platform {
59 class IntRect;
60 }
61 }
62 #endif
63
64 #if USE(CAIRO)
65 typedef struct _cairo_rectangle_int cairo_rectangle_int_t;
66 #endif
67
68 #if PLATFORM(WX)
69 class wxRect;
70 #endif
71
72 #if USE(SKIA)
73 struct SkRect;
74 struct SkIRect;
75 #endif
76
77 namespace WebCore {
78
79 class FloatRect;
80 class FractionalLayoutRect;
81
82 class IntRect {
83 public:
84     IntRect() { }
85     IntRect(const IntPoint& location, const IntSize& size)
86         : m_location(location), m_size(size) { }
87     IntRect(int x, int y, int width, int height)
88         : m_location(IntPoint(x, y)), m_size(IntSize(width, height)) { }
89
90     explicit IntRect(const FloatRect&); // don't do this implicitly since it's lossy
91     explicit IntRect(const FractionalLayoutRect&); // don't do this implicitly since it's lossy
92         
93     IntPoint location() const { return m_location; }
94     IntSize size() const { return m_size; }
95
96     void setLocation(const IntPoint& location) { m_location = location; }
97     void setSize(const IntSize& size) { m_size = size; }
98
99     int x() const { return m_location.x(); }
100     int y() const { return m_location.y(); }
101     int maxX() const { return x() + width(); }
102     int maxY() const { return y() + height(); }
103     int width() const { return m_size.width(); }
104     int height() const { return m_size.height(); }
105
106     // FIXME: These methods are here only to ease the transition to sub-pixel layout. They should
107     // be removed when we close http://webkit.org/b/60318
108     int pixelSnappedX() const { return m_location.x(); }
109     int pixelSnappedY() const { return m_location.y(); }
110     int pixelSnappedMaxX() const { return x() + width(); }
111     int pixelSnappedMaxY() const { return y() + height(); }
112     int pixelSnappedWidth() const { return m_size.width(); }
113     int pixelSnappedHeight() const { return m_size.height(); }
114
115     void setX(int x) { m_location.setX(x); }
116     void setY(int y) { m_location.setY(y); }
117     void setWidth(int width) { m_size.setWidth(width); }
118     void setHeight(int height) { m_size.setHeight(height); }
119
120     bool isEmpty() const { return m_size.isEmpty(); }
121
122     // NOTE: The result is rounded to integer values, and thus may be not the exact
123     // center point.
124     IntPoint center() const { return IntPoint(x() + width() / 2, y() + height() / 2); }
125
126     void move(const IntSize& size) { m_location += size; } 
127     void moveBy(const IntPoint& offset) { m_location.move(offset.x(), offset.y()); }
128     void move(int dx, int dy) { m_location.move(dx, dy); } 
129
130     void expand(const IntSize& size) { m_size += size; }
131     void expand(int dw, int dh) { m_size.expand(dw, dh); }
132     void contract(const IntSize& size) { m_size -= size; }
133     void contract(int dw, int dh) { m_size.expand(-dw, -dh); }
134
135     void shiftXEdgeTo(int edge)
136     {
137         int delta = edge - x();
138         setX(edge);
139         setWidth(std::max(0, width() - delta));
140     }
141     void shiftMaxXEdgeTo(int edge)
142     {
143         int delta = edge - maxX();
144         setWidth(std::max(0, width() + delta));
145     }
146     void shiftYEdgeTo(int edge)
147     {
148         int delta = edge - y();
149         setY(edge);
150         setHeight(std::max(0, height() - delta));
151     }
152     void shiftMaxYEdgeTo(int edge)
153     {
154         int delta = edge - maxY();
155         setHeight(std::max(0, height() + delta));
156     }
157
158     IntPoint minXMinYCorner() const { return m_location; } // typically topLeft
159     IntPoint maxXMinYCorner() const { return IntPoint(m_location.x() + m_size.width(), m_location.y()); } // typically topRight
160     IntPoint minXMaxYCorner() const { return IntPoint(m_location.x(), m_location.y() + m_size.height()); } // typically bottomLeft
161     IntPoint maxXMaxYCorner() const { return IntPoint(m_location.x() + m_size.width(), m_location.y() + m_size.height()); } // typically bottomRight
162     
163     bool intersects(const IntRect&) const;
164     bool contains(const IntRect&) const;
165
166     // This checks to see if the rect contains x,y in the traditional sense.
167     // Equivalent to checking if the rect contains a 1x1 rect below and to the right of (px,py).
168     bool contains(int px, int py) const
169         { return px >= x() && px < maxX() && py >= y() && py < maxY(); }
170     bool contains(const IntPoint& point) const { return contains(point.x(), point.y()); }
171
172     void intersect(const IntRect&);
173     void unite(const IntRect&);
174     void uniteIfNonZero(const IntRect&);
175
176     void inflateX(int dx)
177     {
178         m_location.setX(m_location.x() - dx);
179         m_size.setWidth(m_size.width() + dx + dx);
180     }
181     void inflateY(int dy)
182     {
183         m_location.setY(m_location.y() - dy);
184         m_size.setHeight(m_size.height() + dy + dy);
185     }
186     void inflate(int d) { inflateX(d); inflateY(d); }
187     void scale(float s);
188
189     IntSize differenceToPoint(const IntPoint&) const;
190     IntSize differenceFromCenterLineToPoint(const IntPoint&) const;
191     int distanceSquaredToPoint(const IntPoint& p) const { return differenceToPoint(p).diagonalLengthSquared(); }
192     int distanceSquaredFromCenterLineToPoint(const IntPoint& p) const { return differenceFromCenterLineToPoint(p).diagonalLengthSquared(); }
193
194     IntRect transposedRect() const { return IntRect(m_location.transposedPoint(), m_size.transposedSize()); }
195
196 #if PLATFORM(WX)
197     IntRect(const wxRect&);
198     operator wxRect() const;
199 #endif
200
201 #if PLATFORM(WIN)
202     IntRect(const RECT&);
203     operator RECT() const;
204 #elif PLATFORM(QT)
205     IntRect(const QRect&);
206     operator QRect() const;
207 #elif PLATFORM(GTK)
208 #ifdef GTK_API_VERSION_2
209     IntRect(const GdkRectangle&);
210     operator GdkRectangle() const;
211 #endif
212 #elif PLATFORM(EFL)
213     explicit IntRect(const Eina_Rectangle&);
214     operator Eina_Rectangle() const;
215 #endif
216
217 #if USE(CAIRO)
218     IntRect(const cairo_rectangle_int_t&);
219     operator cairo_rectangle_int_t() const;
220 #endif
221
222 #if USE(CG) || USE(SKIA_ON_MAC_CHROMIUM)
223     operator CGRect() const;
224 #endif
225
226 #if USE(SKIA)
227     IntRect(const SkIRect&);
228     operator SkRect() const;
229     operator SkIRect() const;
230 #endif
231
232 #if (PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)) \
233         || (PLATFORM(CHROMIUM) && OS(DARWIN))  || (PLATFORM(QT) && USE(QTKIT))
234     operator NSRect() const;
235 #endif
236
237 #if PLATFORM(BLACKBERRY)
238     IntRect(const BlackBerry::Platform::IntRect&);
239     operator BlackBerry::Platform::IntRect() const;
240 #endif
241
242 private:
243     IntPoint m_location;
244     IntSize m_size;
245 };
246
247 inline IntRect intersection(const IntRect& a, const IntRect& b)
248 {
249     IntRect c = a;
250     c.intersect(b);
251     return c;
252 }
253
254 inline IntRect unionRect(const IntRect& a, const IntRect& b)
255 {
256     IntRect c = a;
257     c.unite(b);
258     return c;
259 }
260
261 IntRect unionRect(const Vector<IntRect>&);
262
263 inline bool operator==(const IntRect& a, const IntRect& b)
264 {
265     return a.location() == b.location() && a.size() == b.size();
266 }
267
268 inline bool operator!=(const IntRect& a, const IntRect& b)
269 {
270     return a.location() != b.location() || a.size() != b.size();
271 }
272
273 #if USE(CG) || USE(SKIA_ON_MAC_CHROMIUM)
274 IntRect enclosingIntRect(const CGRect&);
275 #endif
276
277 #if (PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)) \
278         || (PLATFORM(CHROMIUM) && OS(DARWIN)) || (PLATFORM(QT) && USE(QTKIT))
279 IntRect enclosingIntRect(const NSRect&);
280 #endif
281
282 } // namespace WebCore
283
284 #endif // IntRect_h