Rect.h revision 60d6922a011fe18c111b8d30fb6ef1f655b6b15e
1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_UI_RECT
18#define ANDROID_UI_RECT
19
20#include <utils/Flattenable.h>
21#include <utils/Log.h>
22#include <utils/TypeHelpers.h>
23#include <ui/Point.h>
24
25#include <android/rect.h>
26
27namespace android {
28
29class Rect : public ARect, public LightFlattenablePod<Rect>
30{
31public:
32    typedef ARect::value_type value_type;
33
34    static const Rect INVALID_RECT;
35    static const Rect EMPTY_RECT;
36
37    // we don't provide copy-ctor and operator= on purpose
38    // because we want the compiler generated versions
39
40    inline Rect() : Rect(INVALID_RECT) {}
41
42    inline Rect(int32_t w, int32_t h) {
43        left = top = 0;
44        right = w;
45        bottom = h;
46    }
47
48    inline Rect(uint32_t w, uint32_t h) {
49        if (w > INT32_MAX) {
50            ALOG(LOG_WARN, "Rect",
51                    "Width %u too large for Rect class, clamping", w);
52            w = INT32_MAX;
53        }
54        if (h > INT32_MAX) {
55            ALOG(LOG_WARN, "Rect",
56                    "Height %u too large for Rect class, clamping", h);
57            h = INT32_MAX;
58        }
59        left = top = 0;
60        right = w;
61        bottom = h;
62    }
63
64    inline Rect(int32_t l, int32_t t, int32_t r, int32_t b) {
65        left = l;
66        top = t;
67        right = r;
68        bottom = b;
69    }
70
71    inline Rect(const Point& lt, const Point& rb) {
72        left = lt.x;
73        top = lt.y;
74        right = rb.x;
75        bottom = rb.y;
76    }
77
78    void makeInvalid();
79
80    inline void clear() {
81        left = top = right = bottom = 0;
82    }
83
84    // a valid rectangle has a non negative width and height
85    inline bool isValid() const {
86        return (getWidth() >= 0) && (getHeight() >= 0);
87    }
88
89    // an empty rect has a zero width or height, or is invalid
90    inline bool isEmpty() const {
91        return (getWidth() <= 0) || (getHeight() <= 0);
92    }
93
94    // rectangle's width
95    inline int32_t getWidth() const {
96        return right - left;
97    }
98
99    // rectangle's height
100    inline int32_t getHeight() const {
101        return bottom - top;
102    }
103
104    inline Rect getBounds() const {
105        return Rect(right - left, bottom - top);
106    }
107
108    void setLeftTop(const Point& lt) {
109        left = lt.x;
110        top = lt.y;
111    }
112
113    void setRightBottom(const Point& rb) {
114        right = rb.x;
115        bottom = rb.y;
116    }
117
118    // the following 4 functions return the 4 corners of the rect as Point
119    Point leftTop() const {
120        return Point(left, top);
121    }
122    Point rightBottom() const {
123        return Point(right, bottom);
124    }
125    Point rightTop() const {
126        return Point(right, top);
127    }
128    Point leftBottom() const {
129        return Point(left, bottom);
130    }
131
132    // comparisons
133    inline bool operator == (const Rect& rhs) const {
134        return (left == rhs.left) && (top == rhs.top) &&
135               (right == rhs.right) && (bottom == rhs.bottom);
136    }
137
138    inline bool operator != (const Rect& rhs) const {
139        return !operator == (rhs);
140    }
141
142    // operator < defines an order which allows to use rectangles in sorted
143    // vectors.
144    bool operator < (const Rect& rhs) const;
145
146    const Rect operator + (const Point& rhs) const;
147    const Rect operator - (const Point& rhs) const;
148
149    Rect& operator += (const Point& rhs) {
150        return offsetBy(rhs.x, rhs.y);
151    }
152    Rect& operator -= (const Point& rhs) {
153        return offsetBy(-rhs.x, -rhs.y);
154    }
155
156    Rect& offsetToOrigin() {
157        right -= left;
158        bottom -= top;
159        left = top = 0;
160        return *this;
161    }
162    Rect& offsetTo(const Point& p) {
163        return offsetTo(p.x, p.y);
164    }
165    Rect& offsetBy(const Point& dp) {
166        return offsetBy(dp.x, dp.y);
167    }
168
169    Rect& offsetTo(int32_t x, int32_t y);
170    Rect& offsetBy(int32_t x, int32_t y);
171
172    bool intersect(const Rect& with, Rect* result) const;
173
174    // Create a new Rect by transforming this one using a graphics HAL
175    // transform.  This rectangle is defined in a coordinate space starting at
176    // the origin and extending to (width, height).  If the transform includes
177    // a ROT90 then the output rectangle is defined in a space extending to
178    // (height, width).  Otherwise the output rectangle is in the same space as
179    // the input.
180    Rect transform(uint32_t xform, int32_t width, int32_t height) const;
181
182    // this calculates (Region(*this) - exclude).bounds() efficiently
183    Rect reduce(const Rect& exclude) const;
184
185
186    // for backward compatibility
187    inline int32_t width() const { return getWidth(); }
188    inline int32_t height() const { return getHeight(); }
189    inline void set(const Rect& rhs) { operator = (rhs); }
190};
191
192ANDROID_BASIC_TYPES_TRAITS(Rect)
193
194}; // namespace android
195
196#endif // ANDROID_UI_RECT
197