1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#ifndef ANDROID_UI_RECT
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define ANDROID_UI_RECT
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
208683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian#include <utils/Flattenable.h>
21dd883c0b08d2a60f89542b9b9f5fdabcb14885c7Dan Stoza#include <utils/Log.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/TypeHelpers.h>
237823e124e00576e20e47ec717cbe8bc89f0f2bf2Mark Salyzyn#include <log/log.h>
247823e124e00576e20e47ec717cbe8bc89f0f2bf2Mark Salyzyn
255a423eaa86f4c990afcef8c55e3949d0872068b4Dan Stoza#include <ui/FloatRect.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Point.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
289147d11a5f1d50496908bb1f49996e3ad23e19ccDianne Hackborn#include <android/rect.h>
299147d11a5f1d50496908bb1f49996e3ad23e19ccDianne Hackborn
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
328683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopianclass Rect : public ARect, public LightFlattenablePod<Rect>
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectpublic:
35000e95e7ebf1a60bbb7fda604b54092f45c87f89Mathias Agopian    typedef ARect::value_type value_type;
364b8160fdfd3281d1d66c0cae9bb9c647b4333491Mathias Agopian
375065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza    static const Rect INVALID_RECT;
3860d6922a011fe18c111b8d30fb6ef1f655b6b15ePablo Ceballos    static const Rect EMPTY_RECT;
395065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // we don't provide copy-ctor and operator= on purpose
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // because we want the compiler generated versions
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4360d6922a011fe18c111b8d30fb6ef1f655b6b15ePablo Ceballos    inline Rect() : Rect(INVALID_RECT) {}
446c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian
454e643af56d8805b24cccb0ceb6b67a24cf437fb7Dan Stoza    template <typename T>
464e643af56d8805b24cccb0ceb6b67a24cf437fb7Dan Stoza    inline Rect(T w, T h) {
47dd883c0b08d2a60f89542b9b9f5fdabcb14885c7Dan Stoza        if (w > INT32_MAX) {
48dd883c0b08d2a60f89542b9b9f5fdabcb14885c7Dan Stoza            w = INT32_MAX;
49dd883c0b08d2a60f89542b9b9f5fdabcb14885c7Dan Stoza        }
50dd883c0b08d2a60f89542b9b9f5fdabcb14885c7Dan Stoza        if (h > INT32_MAX) {
51dd883c0b08d2a60f89542b9b9f5fdabcb14885c7Dan Stoza            h = INT32_MAX;
52dd883c0b08d2a60f89542b9b9f5fdabcb14885c7Dan Stoza        }
53dd883c0b08d2a60f89542b9b9f5fdabcb14885c7Dan Stoza        left = top = 0;
544e643af56d8805b24cccb0ceb6b67a24cf437fb7Dan Stoza        right = static_cast<int32_t>(w);
554e643af56d8805b24cccb0ceb6b67a24cf437fb7Dan Stoza        bottom = static_cast<int32_t>(h);
56dd883c0b08d2a60f89542b9b9f5fdabcb14885c7Dan Stoza    }
57dd883c0b08d2a60f89542b9b9f5fdabcb14885c7Dan Stoza
589147d11a5f1d50496908bb1f49996e3ad23e19ccDianne Hackborn    inline Rect(int32_t l, int32_t t, int32_t r, int32_t b) {
596c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian        left = l;
606c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian        top = t;
616c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian        right = r;
626c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian        bottom = b;
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
646c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian
659147d11a5f1d50496908bb1f49996e3ad23e19ccDianne Hackborn    inline Rect(const Point& lt, const Point& rb) {
666c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian        left = lt.x;
676c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian        top = lt.y;
686c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian        right = rb.x;
696c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian        bottom = rb.y;
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    void makeInvalid();
734b8160fdfd3281d1d66c0cae9bb9c647b4333491Mathias Agopian
744b8160fdfd3281d1d66c0cae9bb9c647b4333491Mathias Agopian    inline void clear() {
754b8160fdfd3281d1d66c0cae9bb9c647b4333491Mathias Agopian        left = top = right = bottom = 0;
764b8160fdfd3281d1d66c0cae9bb9c647b4333491Mathias Agopian    }
774b8160fdfd3281d1d66c0cae9bb9c647b4333491Mathias Agopian
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // a valid rectangle has a non negative width and height
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    inline bool isValid() const {
806c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian        return (getWidth() >= 0) && (getHeight() >= 0);
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // an empty rect has a zero width or height, or is invalid
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    inline bool isEmpty() const {
856c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian        return (getWidth() <= 0) || (getHeight() <= 0);
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // rectangle's width
89b82203a6601728a507bc3e7d5b2b042356004aaeMathias Agopian    inline int32_t getWidth() const {
906c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian        return right - left;
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
926c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // rectangle's height
94b82203a6601728a507bc3e7d5b2b042356004aaeMathias Agopian    inline int32_t getHeight() const {
956c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian        return bottom - top;
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
98b82203a6601728a507bc3e7d5b2b042356004aaeMathias Agopian    inline Rect getBounds() const {
996c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian        return Rect(right - left, bottom - top);
100b82203a6601728a507bc3e7d5b2b042356004aaeMathias Agopian    }
101b82203a6601728a507bc3e7d5b2b042356004aaeMathias Agopian
10235801cea5f301c0e1d7a93b15a8f73f98e6b1033Mathias Agopian    void setLeftTop(const Point& lt) {
10335801cea5f301c0e1d7a93b15a8f73f98e6b1033Mathias Agopian        left = lt.x;
1046c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian        top = lt.y;
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
10635801cea5f301c0e1d7a93b15a8f73f98e6b1033Mathias Agopian
10735801cea5f301c0e1d7a93b15a8f73f98e6b1033Mathias Agopian    void setRightBottom(const Point& rb) {
10835801cea5f301c0e1d7a93b15a8f73f98e6b1033Mathias Agopian        right = rb.x;
1096c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian        bottom = rb.y;
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // the following 4 functions return the 4 corners of the rect as Point
11335801cea5f301c0e1d7a93b15a8f73f98e6b1033Mathias Agopian    Point leftTop() const {
11435801cea5f301c0e1d7a93b15a8f73f98e6b1033Mathias Agopian        return Point(left, top);
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
11635801cea5f301c0e1d7a93b15a8f73f98e6b1033Mathias Agopian    Point rightBottom() const {
11735801cea5f301c0e1d7a93b15a8f73f98e6b1033Mathias Agopian        return Point(right, bottom);
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Point rightTop() const {
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return Point(right, top);
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Point leftBottom() const {
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return Point(left, bottom);
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // comparisons
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    inline bool operator == (const Rect& rhs) const {
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return (left == rhs.left) && (top == rhs.top) &&
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project               (right == rhs.right) && (bottom == rhs.bottom);
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    inline bool operator != (const Rect& rhs) const {
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return !operator == (rhs);
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // operator < defines an order which allows to use rectangles in sorted
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // vectors.
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool operator < (const Rect& rhs) const;
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1406c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    const Rect operator + (const Point& rhs) const;
1416c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    const Rect operator - (const Point& rhs) const;
1426c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian
1436c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    Rect& operator += (const Point& rhs) {
1446c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian        return offsetBy(rhs.x, rhs.y);
1456c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    }
1466c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    Rect& operator -= (const Point& rhs) {
1476c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian        return offsetBy(-rhs.x, -rhs.y);
1486c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    }
1496c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Rect& offsetToOrigin() {
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        right -= left;
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        bottom -= top;
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        left = top = 0;
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return *this;
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Rect& offsetTo(const Point& p) {
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return offsetTo(p.x, p.y);
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Rect& offsetBy(const Point& dp) {
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return offsetBy(dp.x, dp.y);
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1636c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    Rect& offsetTo(int32_t x, int32_t y);
1646c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    Rect& offsetBy(int32_t x, int32_t y);
16559332804306c054082a39e9b004146bd03ae1d30Jamie Gennis
1666c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    bool intersect(const Rect& with, Rect* result) const;
16759332804306c054082a39e9b004146bd03ae1d30Jamie Gennis
16859332804306c054082a39e9b004146bd03ae1d30Jamie Gennis    // Create a new Rect by transforming this one using a graphics HAL
16959332804306c054082a39e9b004146bd03ae1d30Jamie Gennis    // transform.  This rectangle is defined in a coordinate space starting at
17059332804306c054082a39e9b004146bd03ae1d30Jamie Gennis    // the origin and extending to (width, height).  If the transform includes
17159332804306c054082a39e9b004146bd03ae1d30Jamie Gennis    // a ROT90 then the output rectangle is defined in a space extending to
17259332804306c054082a39e9b004146bd03ae1d30Jamie Gennis    // (height, width).  Otherwise the output rectangle is in the same space as
17359332804306c054082a39e9b004146bd03ae1d30Jamie Gennis    // the input.
174f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis    Rect transform(uint32_t xform, int32_t width, int32_t height) const;
1756c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian
176f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    // this calculates (Region(*this) - exclude).bounds() efficiently
177f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian    Rect reduce(const Rect& exclude) const;
178f3e85d432749ca77ad707bec523b67d741d43e6eMathias Agopian
1796c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    // for backward compatibility
1806c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    inline int32_t width() const { return getWidth(); }
1816c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    inline int32_t height() const { return getHeight(); }
1826c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian    inline void set(const Rect& rhs) { operator = (rhs); }
18371bded513d37a6c1260b4a62c69ecc0d24be95f7Dan Stoza
1845a423eaa86f4c990afcef8c55e3949d0872068b4Dan Stoza    FloatRect toFloatRect() const {
18571bded513d37a6c1260b4a62c69ecc0d24be95f7Dan Stoza        return {static_cast<float>(left), static_cast<float>(top),
18671bded513d37a6c1260b4a62c69ecc0d24be95f7Dan Stoza                static_cast<float>(right), static_cast<float>(bottom)};
18771bded513d37a6c1260b4a62c69ecc0d24be95f7Dan Stoza    }
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project};
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectANDROID_BASIC_TYPES_TRAITS(Rect)
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif // ANDROID_UI_RECT
195