Rect.h revision 83b186a246e8ffd52b91a17c0019dd8c9c9d21b1
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 Agopian    static inline float min(float a, float b) { return (a<b) ? a : b; }
3383b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian    static inline float max(float a, float b) { return (a>b) ? a : b; }
3483b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian    Rect intersectWith(float l, float t, float r, float b) const {
3583b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian        Rect tmp;
3683b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian        tmp.left    = max(left, l);
3783b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian        tmp.top     = max(top, t);
3883b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian        tmp.right   = min(right, r);
3983b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian        tmp.bottom  = min(bottom, b);
4083b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian        return tmp;
4183b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian    }
4283b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian
4383b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopianpublic:
447ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    float left;
457ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    float top;
467ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    float right;
477ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    float bottom;
487ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
495b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    // Used by Region
505b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    typedef float value_type;
515b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
5283b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian    // we don't provide copy-ctor and operator= on purpose
5383b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian    // because we want the compiler generated versions
5483b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian
555b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline Rect():
567ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            left(0),
577ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            top(0),
587ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            right(0),
597ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            bottom(0) {
607ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
617ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
625b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline Rect(float left, float top, float right, float bottom):
637ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            left(left),
647ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            top(top),
657ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            right(right),
667ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            bottom(bottom) {
677ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
687ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
695b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline Rect(float width, float height):
705b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            left(0.0f),
715b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            top(0.0f),
725b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            right(width),
735b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            bottom(height) {
745b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    }
755b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
767ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    friend int operator==(const Rect& a, const Rect& b) {
777ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return !memcmp(&a, &b, sizeof(a));
787ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
797ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
807ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    friend int operator!=(const Rect& a, const Rect& b) {
817ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return memcmp(&a, &b, sizeof(a));
827ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
837ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
845b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline void clear() {
855b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        left = top = right = bottom = 0.0f;
865b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    }
875b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
885b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline bool isEmpty() const {
8983b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian        // this is written in such way this it'll handle NANs to return
9083b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian        // true (empty)
9183b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian        return !((left < right) && (top < bottom));
927ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
937ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
945b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline void setEmpty() {
955b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        left = top = right = bottom = 0.0f;
967ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
977ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
985b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline void set(float left, float top, float right, float bottom) {
997ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        this->left = left;
1007ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        this->right = right;
1017ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        this->top = top;
1027ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        this->bottom = bottom;
1037ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1047ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
1055b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline void set(const Rect& r) {
1067ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        set(r.left, r.top, r.right, r.bottom);
1077ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1087ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
1098aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    inline float getWidth() const {
1107ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return right - left;
1117ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1127ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
1138aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    inline float getHeight() const {
1147ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return bottom - top;
1157ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1167ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
11783b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian    bool intersects(float l, float t, float r, float b) const {
11883b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian        return !intersectWith(l,t,r,b).isEmpty();
1197ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1207ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
1217ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    bool intersects(const Rect& r) const {
1227ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return intersects(r.left, r.top, r.right, r.bottom);
1237ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1247ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
12583b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian    bool intersect(float l, float t, float r, float b) {
12683b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian        Rect tmp(intersectWith(l,t,r,b));
12783b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian        if (!tmp.isEmpty()) {
12883b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian            set(tmp);
1297ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            return true;
1307ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        }
1317ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return false;
1327ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1337ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
1347ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    bool intersect(const Rect& r) {
1357ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return intersect(r.left, r.top, r.right, r.bottom);
1367ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1377ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
138079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy    bool unionWith(const Rect& r) {
139079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        if (r.left < r.right && r.top < r.bottom) {
140079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy            if (left < right && top < bottom) {
141079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                if (left > r.left) left = r.left;
142079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                if (top > r.top) top = r.top;
143079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                if (right < r.right) right = r.right;
144079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                if (bottom < r.bottom) bottom = r.bottom;
145079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                return true;
146079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy            } else {
147079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                left = r.left;
148079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                top = r.top;
149079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                right = r.right;
150079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                bottom = r.bottom;
151079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                return true;
152079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy            }
153079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        }
154079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        return false;
155079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy    }
156079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
1575b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    void translate(float dx, float dy) {
1585b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        left += dx;
1595b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        right += dx;
1605b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        top += dy;
1615b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        bottom += dy;
1625b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    }
1635b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
164bf434114cbf55b216fdc76fc8d65a75e84c9dab5Romain Guy    void snapToPixelBoundaries() {
165ae88e5e8e9cb6c9539314c4360c5b20f8ec1fefcRomain Guy        left = floorf(left + 0.5f);
166ae88e5e8e9cb6c9539314c4360c5b20f8ec1fefcRomain Guy        top = floorf(top + 0.5f);
167ae88e5e8e9cb6c9539314c4360c5b20f8ec1fefcRomain Guy        right = floorf(right + 0.5f);
168ae88e5e8e9cb6c9539314c4360c5b20f8ec1fefcRomain Guy        bottom = floorf(bottom + 0.5f);
169bf434114cbf55b216fdc76fc8d65a75e84c9dab5Romain Guy    }
170bf434114cbf55b216fdc76fc8d65a75e84c9dab5Romain Guy
1717ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void dump() const {
1727ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        LOGD("Rect[l=%f t=%f r=%f b=%f]", left, top, right, bottom);
1737ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
174bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
17583b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian}; // class Rect
176bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
1779d5316e3f56d138504565ff311145ac01621dff4Romain Guy}; // namespace uirenderer
178bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}; // namespace android
179bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
1805b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#endif // ANDROID_HWUI_RECT_H
181