Rect.h revision 5e49b307eb99269db2db257760508b8efd7bb97d
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
2739a908c1df89e1073627b0dcbce922d826b67055Chris Craik#define RECT_STRING "%7.2f %7.2f %7.2f %7.2f"
2828ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik#define RECT_ARGS(r) \
2928ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik    (r).left, (r).top, (r).right, (r).bottom
3028ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik
31bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy///////////////////////////////////////////////////////////////////////////////
32bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy// Structs
33bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy///////////////////////////////////////////////////////////////////////////////
34bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
3583b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopianclass Rect {
3683b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopianpublic:
377ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    float left;
387ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    float top;
397ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    float right;
407ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    float bottom;
417ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
425b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    // Used by Region
435b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    typedef float value_type;
445b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
4583b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian    // we don't provide copy-ctor and operator= on purpose
4683b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian    // because we want the compiler generated versions
4783b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian
485b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline Rect():
497ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            left(0),
507ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            top(0),
517ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            right(0),
527ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            bottom(0) {
537ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
547ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
555b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline Rect(float left, float top, float right, float bottom):
567ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            left(left),
577ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            top(top),
587ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            right(right),
597ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            bottom(bottom) {
607ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
617ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
625b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline Rect(float width, float height):
635b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            left(0.0f),
645b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            top(0.0f),
655b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            right(width),
665b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            bottom(height) {
675b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    }
685b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
697ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    friend int operator==(const Rect& a, const Rect& b) {
707ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return !memcmp(&a, &b, sizeof(a));
717ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
727ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
737ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    friend int operator!=(const Rect& a, const Rect& b) {
747ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return memcmp(&a, &b, sizeof(a));
757ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
767ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
775b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline void clear() {
785b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        left = top = right = bottom = 0.0f;
795b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    }
805b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
815b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline bool isEmpty() const {
8283b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian        // this is written in such way this it'll handle NANs to return
8383b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian        // true (empty)
8483b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian        return !((left < right) && (top < bottom));
857ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
867ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
875b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline void setEmpty() {
885b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        left = top = right = bottom = 0.0f;
897ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
907ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
915b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline void set(float left, float top, float right, float bottom) {
927ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        this->left = left;
937ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        this->right = right;
947ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        this->top = top;
957ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        this->bottom = bottom;
967ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
977ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
985b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    inline void set(const Rect& r) {
997ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        set(r.left, r.top, r.right, r.bottom);
1007ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1017ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
1028aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    inline float getWidth() const {
1037ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return right - left;
1047ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1057ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
1068aef54fa17f2a3753d9a8f2027629bc480088f69Romain Guy    inline float getHeight() const {
1077ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return bottom - top;
1087ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1097ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
11083b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian    bool intersects(float l, float t, float r, float b) const {
111a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy        return !intersectWith(l, t, r, b).isEmpty();
1127ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1137ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
1147ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    bool intersects(const Rect& r) const {
1157ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return intersects(r.left, r.top, r.right, r.bottom);
1167ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1177ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
11883b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian    bool intersect(float l, float t, float r, float b) {
1198f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy        Rect tmp(l, t, r, b);
1208f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy        intersectWith(tmp);
12183b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian        if (!tmp.isEmpty()) {
12283b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian            set(tmp);
1237ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            return true;
1247ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        }
1257ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return false;
1267ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1277ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
1287ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    bool intersect(const Rect& r) {
1297ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        return intersect(r.left, r.top, r.right, r.bottom);
1307ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
1317ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy
1322db5e993b626794eb07a0ff354269f9a77da81b3Romain Guy    inline bool contains(float l, float t, float r, float b) const {
133ec31f83bd3af1f900d1ee9116b15f56904c66dcdRomain Guy        return l >= left && t >= top && r <= right && b <= bottom;
134ec31f83bd3af1f900d1ee9116b15f56904c66dcdRomain Guy    }
135ec31f83bd3af1f900d1ee9116b15f56904c66dcdRomain Guy
1362db5e993b626794eb07a0ff354269f9a77da81b3Romain Guy    inline bool contains(const Rect& r) const {
137ec31f83bd3af1f900d1ee9116b15f56904c66dcdRomain Guy        return contains(r.left, r.top, r.right, r.bottom);
138ec31f83bd3af1f900d1ee9116b15f56904c66dcdRomain Guy    }
139ec31f83bd3af1f900d1ee9116b15f56904c66dcdRomain Guy
140079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy    bool unionWith(const Rect& r) {
141079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        if (r.left < r.right && r.top < r.bottom) {
142079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy            if (left < right && top < bottom) {
143079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                if (left > r.left) left = r.left;
144079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                if (top > r.top) top = r.top;
145079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                if (right < r.right) right = r.right;
146079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                if (bottom < r.bottom) bottom = r.bottom;
147079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                return true;
148079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy            } else {
149079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                left = r.left;
150079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                top = r.top;
151079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                right = r.right;
152079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                bottom = r.bottom;
153079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy                return true;
154079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy            }
155079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        }
156079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy        return false;
157079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy    }
158079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
1595b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    void translate(float dx, float dy) {
1605b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        left += dx;
1615b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        right += dx;
1625b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        top += dy;
1635b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        bottom += dy;
1645b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    }
1655b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
166c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik    void outset(float delta) {
167c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik        left -= delta;
168c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik        top -= delta;
169c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik        right += delta;
170c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik        bottom += delta;
171c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik    }
172c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik
1735e49b307eb99269db2db257760508b8efd7bb97dChris Craik    /**
1745e49b307eb99269db2db257760508b8efd7bb97dChris Craik     * Similar to snapToPixelBoundaries, but used for AA geometry with a ramp perimeter.
1755e49b307eb99269db2db257760508b8efd7bb97dChris Craik     *
1765e49b307eb99269db2db257760508b8efd7bb97dChris Craik     * We inset the data by a fudge factor of slightly over 1/16 (similar to when drawing non-AA
1775e49b307eb99269db2db257760508b8efd7bb97dChris Craik     * lines) before rounding out so that insignificant amounts of ramp geometry (esp. from rounding
1785e49b307eb99269db2db257760508b8efd7bb97dChris Craik     * errors) are ignored.
1795e49b307eb99269db2db257760508b8efd7bb97dChris Craik     */
1805e49b307eb99269db2db257760508b8efd7bb97dChris Craik    void snapOutToPixelBoundaries() {
1815e49b307eb99269db2db257760508b8efd7bb97dChris Craik        left = floorf(left + 0.065f);
1825e49b307eb99269db2db257760508b8efd7bb97dChris Craik        top = floorf(top + 0.065f);
1835e49b307eb99269db2db257760508b8efd7bb97dChris Craik        right = ceilf(right - 0.065f);
1845e49b307eb99269db2db257760508b8efd7bb97dChris Craik        bottom = ceilf(bottom - 0.065f);
1855e49b307eb99269db2db257760508b8efd7bb97dChris Craik    }
1865e49b307eb99269db2db257760508b8efd7bb97dChris Craik
187bf434114cbf55b216fdc76fc8d65a75e84c9dab5Romain Guy    void snapToPixelBoundaries() {
188ae88e5e8e9cb6c9539314c4360c5b20f8ec1fefcRomain Guy        left = floorf(left + 0.5f);
189ae88e5e8e9cb6c9539314c4360c5b20f8ec1fefcRomain Guy        top = floorf(top + 0.5f);
190ae88e5e8e9cb6c9539314c4360c5b20f8ec1fefcRomain Guy        right = floorf(right + 0.5f);
191ae88e5e8e9cb6c9539314c4360c5b20f8ec1fefcRomain Guy        bottom = floorf(bottom + 0.5f);
192bf434114cbf55b216fdc76fc8d65a75e84c9dab5Romain Guy    }
193bf434114cbf55b216fdc76fc8d65a75e84c9dab5Romain Guy
1947ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void dump() const {
1955baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Rect[l=%f t=%f r=%f b=%f]", left, top, right, bottom);
1967ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
197bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
198a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guyprivate:
1998f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy    void intersectWith(Rect& tmp) const {
2002af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        tmp.left = fmaxf(left, tmp.left);
2012af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        tmp.top = fmaxf(top, tmp.top);
2022af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        tmp.right = fminf(right, tmp.right);
2032af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        tmp.bottom = fminf(bottom, tmp.bottom);
2048f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy    }
2058f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy
206a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy    Rect intersectWith(float l, float t, float r, float b) const {
207a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy        Rect tmp;
2082af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        tmp.left = fmaxf(left, l);
2092af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        tmp.top = fmaxf(top, t);
2102af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        tmp.right = fminf(right, r);
2112af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        tmp.bottom = fminf(bottom, b);
212a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy        return tmp;
213a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy    }
214a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy
21583b186a246e8ffd52b91a17c0019dd8c9c9d21b1Mathias Agopian}; // class Rect
216bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
2179d5316e3f56d138504565ff311145ac01621dff4Romain Guy}; // namespace uirenderer
218bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}; // namespace android
219bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
2205b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#endif // ANDROID_HWUI_RECT_H
221