Rect.h revision 8f85e80b64b89fd38cc23b129f61ec36ddde7f15
1bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy/*
2bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy * Copyright (C) 2010 The Android Open Source Project
3bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy *
4bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
5bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy * you may not use this file except in compliance with the License.
6bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy * You may obtain a copy of the License at
7bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy *
8bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
9bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy *
10bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy * Unless required by applicable law or agreed to in writing, software
11bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
12bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy * See the License for the specific language governing permissions and
14bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy * limitations under the License.
15bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy */
16bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
175b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#ifndef ANDROID_HWUI_RECT_H
185b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#define ANDROID_HWUI_RECT_H
195b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
205b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#include <cmath>
21bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
225cbbce535744b89df5ecea95de21ee3733298260Romain Guy#include <utils/Log.h>
235cbbce535744b89df5ecea95de21ee3733298260Romain Guy
24bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guynamespace android {
259d5316e3f56d138504565ff311145ac01621dff4Romain Guynamespace uirenderer {
26bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
27bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy///////////////////////////////////////////////////////////////////////////////
28bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy// Structs
29bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy///////////////////////////////////////////////////////////////////////////////
30bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
3183b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopianclass Rect {
3283b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopianpublic:
337ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    float left;
347ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    float top;
357ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    float right;
367ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    float bottom;
377ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
385b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    // Used by Region
395b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    typedef float value_type;
405b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
4183b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian    // we don't provide copy-ctor and operator= on purpose
4283b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian    // because we want the compiler generated versions
4383b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian
445b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline Rect():
457ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            left(0),
467ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            top(0),
477ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            right(0),
487ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            bottom(0) {
497ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
507ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
515b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline Rect(float left, float top, float right, float bottom):
527ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            left(left),
537ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            top(top),
547ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            right(right),
557ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            bottom(bottom) {
567ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
577ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
585b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline Rect(float width, float height):
595b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            left(0.0f),
605b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            top(0.0f),
615b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            right(width),
625b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            bottom(height) {
635b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    }
645b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
657ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    friend int operator==(const Rect& a, const Rect& b) {
667ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return !memcmp(&a, &b, sizeof(a));
677ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
687ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
697ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    friend int operator!=(const Rect& a, const Rect& b) {
707ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return memcmp(&a, &b, sizeof(a));
717ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
727ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
735b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline void clear() {
745b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        left = top = right = bottom = 0.0f;
755b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    }
765b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
775b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline bool isEmpty() const {
7883b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian        // this is written in such way this it'll handle NANs to return
7983b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian        // true (empty)
8083b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian        return !((left < right) && (top < bottom));
817ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
827ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
835b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline void setEmpty() {
845b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        left = top = right = bottom = 0.0f;
857ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
867ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
875b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline void set(float left, float top, float right, float bottom) {
887ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        this->left = left;
897ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        this->right = right;
907ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        this->top = top;
917ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        this->bottom = bottom;
927ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
937ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
945b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline void set(const Rect& r) {
957ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        set(r.left, r.top, r.right, r.bottom);
967ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
977ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
988aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    inline float getWidth() const {
997ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return right - left;
1007ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1017ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
1028aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    inline float getHeight() const {
1037ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return bottom - top;
1047ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1057ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
10683b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian    bool intersects(float l, float t, float r, float b) const {
107a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy        return !intersectWith(l, t, r, b).isEmpty();
1087ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1097ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
1107ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    bool intersects(const Rect& r) const {
1117ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return intersects(r.left, r.top, r.right, r.bottom);
1127ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1137ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
11483b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian    bool intersect(float l, float t, float r, float b) {
1158f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy        Rect tmp(l, t, r, b);
1168f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy        intersectWith(tmp);
11783b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian        if (!tmp.isEmpty()) {
11883b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian            set(tmp);
1197ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            return true;
1207ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        }
1217ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return false;
1227ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1237ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
1247ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    bool intersect(const Rect& r) {
1257ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return intersect(r.left, r.top, r.right, r.bottom);
1267ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1277ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
128ec31f83bd3af1f900d1ee9116b15f56904c66dcdRomain Guy    bool contains(float l, float t, float r, float b) {
129ec31f83bd3af1f900d1ee9116b15f56904c66dcdRomain Guy        return l >= left && t >= top && r <= right && b <= bottom;
130ec31f83bd3af1f900d1ee9116b15f56904c66dcdRomain Guy    }
131ec31f83bd3af1f900d1ee9116b15f56904c66dcdRomain Guy
132ec31f83bd3af1f900d1ee9116b15f56904c66dcdRomain Guy    bool contains(const Rect& r) {
133ec31f83bd3af1f900d1ee9116b15f56904c66dcdRomain Guy        return contains(r.left, r.top, r.right, r.bottom);
134ec31f83bd3af1f900d1ee9116b15f56904c66dcdRomain Guy    }
135ec31f83bd3af1f900d1ee9116b15f56904c66dcdRomain Guy
136079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy    bool unionWith(const Rect& r) {
137079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        if (r.left < r.right && r.top < r.bottom) {
138079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy            if (left < right && top < bottom) {
139079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                if (left > r.left) left = r.left;
140079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                if (top > r.top) top = r.top;
141079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                if (right < r.right) right = r.right;
142079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                if (bottom < r.bottom) bottom = r.bottom;
143079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                return true;
144079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy            } else {
145079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                left = r.left;
146079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                top = r.top;
147079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                right = r.right;
148079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                bottom = r.bottom;
149079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                return true;
150079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy            }
151079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        }
152079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        return false;
153079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy    }
154079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
1555b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    void translate(float dx, float dy) {
1565b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        left += dx;
1575b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        right += dx;
1585b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        top += dy;
1595b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        bottom += dy;
1605b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    }
1615b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
162bf434114cbf55b216fdc76fc8d65a75e84c9dab5Romain Guy    void snapToPixelBoundaries() {
163ae88e5e8e9cb6c9539314c4360c5b20f8ec1fefcRomain Guy        left = floorf(left + 0.5f);
164ae88e5e8e9cb6c9539314c4360c5b20f8ec1fefcRomain Guy        top = floorf(top + 0.5f);
165ae88e5e8e9cb6c9539314c4360c5b20f8ec1fefcRomain Guy        right = floorf(right + 0.5f);
166ae88e5e8e9cb6c9539314c4360c5b20f8ec1fefcRomain Guy        bottom = floorf(bottom + 0.5f);
167bf434114cbf55b216fdc76fc8d65a75e84c9dab5Romain Guy    }
168bf434114cbf55b216fdc76fc8d65a75e84c9dab5Romain Guy
1697ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void dump() const {
1707ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        LOGD("Rect[l=%f t=%f r=%f b=%f]", left, top, right, bottom);
1717ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
172bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
173a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guyprivate:
174a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy    static inline float min(float a, float b) { return (a < b) ? a : b; }
175a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy    static inline float max(float a, float b) { return (a > b) ? a : b; }
176a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy
1778f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy    void intersectWith(Rect& tmp) const {
1788f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy        tmp.left = max(left, tmp.left);
1798f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy        tmp.top = max(top, tmp.top);
1808f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy        tmp.right = min(right, tmp.right);
1818f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy        tmp.bottom = min(bottom, tmp.bottom);
1828f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy    }
1838f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy
184a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy    Rect intersectWith(float l, float t, float r, float b) const {
185a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy        Rect tmp;
186a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy        tmp.left = max(left, l);
187a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy        tmp.top = max(top, t);
188a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy        tmp.right = min(right, r);
189a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy        tmp.bottom = min(bottom, b);
190a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy        return tmp;
191a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy    }
192a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy
19383b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian}; // class Rect
194bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
1959d5316e3f56d138504565ff311145ac01621dff4Romain Guy}; // namespace uirenderer
196bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}; // namespace android
197bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
1985b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#endif // ANDROID_HWUI_RECT_H
199