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)
33typedef struct CGRect CGRect;
34#endif
35
36#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
37#ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES
38typedef struct CGRect NSRect;
39#else
40typedef struct _NSRect NSRect;
41#endif
42#endif
43
44#if PLATFORM(WIN)
45typedef struct tagRECT RECT;
46#elif PLATFORM(QT)
47QT_BEGIN_NAMESPACE
48class QRect;
49QT_END_NAMESPACE
50#elif PLATFORM(GTK)
51#ifdef GTK_API_VERSION_2
52typedef struct _GdkRectangle GdkRectangle;
53#else
54typedef struct _cairo_rectangle_int cairo_rectangle_int_t;
55typedef cairo_rectangle_int_t GdkRectangle;
56#endif
57#elif PLATFORM(HAIKU)
58class BRect;
59#elif PLATFORM(EFL)
60typedef struct _Eina_Rectangle Eina_Rectangle;
61#endif
62
63#if PLATFORM(WX)
64class wxRect;
65#endif
66
67#if USE(SKIA)
68struct SkRect;
69struct SkIRect;
70#endif
71
72namespace WebCore {
73
74class FloatRect;
75
76class IntRect {
77public:
78    IntRect() { }
79    IntRect(const IntPoint& location, const IntSize& size)
80        : m_location(location), m_size(size) { }
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
86    IntPoint location() const { return m_location; }
87    IntSize size() const { return m_size; }
88
89    void setLocation(const IntPoint& location) { m_location = location; }
90    void setSize(const IntSize& size) { m_size = size; }
91
92    int x() const { return m_location.x(); }
93    int y() const { return m_location.y(); }
94    int maxX() const { return x() + width(); }
95    int maxY() const { return y() + height(); }
96    int width() const { return m_size.width(); }
97    int height() const { return m_size.height(); }
98
99    void setX(int x) { m_location.setX(x); }
100    void setY(int y) { m_location.setY(y); }
101    void setWidth(int width) { m_size.setWidth(width); }
102    void setHeight(int height) { m_size.setHeight(height); }
103
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.
108    IntPoint center() const { return IntPoint(x() + width() / 2, y() + height() / 2); }
109
110    void move(const IntSize& s) { m_location += s; }
111    void move(int dx, int dy) { m_location.move(dx, dy); }
112
113    void shiftXEdgeTo(int edge)
114    {
115        int delta = edge - x();
116        setX(edge);
117        setWidth(std::max(0, width() - delta));
118    }
119    void shiftMaxXEdgeTo(int edge)
120    {
121        int delta = edge - maxX();
122        setWidth(std::max(0, width() + delta));
123    }
124    void shiftYEdgeTo(int edge)
125    {
126        int delta = edge - y();
127        setY(edge);
128        setHeight(std::max(0, height() - delta));
129    }
130    void shiftMaxYEdgeTo(int edge)
131    {
132        int delta = edge - maxY();
133        setHeight(std::max(0, height() + delta));
134    }
135
136    IntPoint minXMinYCorner() const { return m_location; } // typically topLeft
137    IntPoint maxXMinYCorner() const { return IntPoint(m_location.x() + m_size.width(), m_location.y()); } // typically topRight
138    IntPoint minXMaxYCorner() const { return IntPoint(m_location.x(), m_location.y() + m_size.height()); } // typically bottomLeft
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).
146    bool contains(int px, int py) const
147        { return px >= x() && px < maxX() && py >= y() && py < maxY(); }
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
154    void inflateX(int dx)
155    {
156        m_location.setX(m_location.x() - dx);
157        m_size.setWidth(m_size.width() + dx + dx);
158    }
159    void inflateY(int dy)
160    {
161        m_location.setY(m_location.y() - dy);
162        m_size.setHeight(m_size.height() + dy + dy);
163    }
164    void inflate(int d) { inflateX(d); inflateY(d); }
165    void scale(float s);
166
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))
203    operator NSRect() const;
204#endif
205
206private:
207    IntPoint m_location;
208    IntSize m_size;
209};
210
211inline IntRect intersection(const IntRect& a, const IntRect& b)
212{
213    IntRect c = a;
214    c.intersect(b);
215    return c;
216}
217
218inline IntRect unionRect(const IntRect& a, const IntRect& b)
219{
220    IntRect c = a;
221    c.unite(b);
222    return c;
223}
224
225IntRect unionRect(const Vector<IntRect>&);
226
227inline bool operator==(const IntRect& a, const IntRect& b)
228{
229    return a.location() == b.location() && a.size() == b.size();
230}
231
232inline 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)
238IntRect enclosingIntRect(const CGRect&);
239#endif
240
241#if (PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)) \
242        || (PLATFORM(CHROMIUM) && OS(DARWIN))
243IntRect enclosingIntRect(const NSRect&);
244#endif
245
246} // namespace WebCore
247
248#endif // IntRect_h
249