1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
3 
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10 
11  * The above copyright notice and this permission notice shall be included in all
12  * copies or substantial portions of the Software.
13 
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  */
22 
23 #ifndef VRECT_H
24 #define VRECT_H
25 #include "vglobal.h"
26 #include "vpoint.h"
27 
28 V_BEGIN_NAMESPACE
29 class VRectF;
30 
31 class VRect {
32 public:
33     VRect() = default;
VRect(int x,int y,int w,int h)34     VRect(int x, int y, int w, int h):x1(x),y1(y),x2(x+w),y2(y+h){}
VRect(VPoint pt,VSize sz)35     explicit VRect(VPoint pt, VSize sz):VRect(pt.x(), pt.y(), sz.width(), sz.height()){}
36     operator VRectF() const;
empty()37     V_CONSTEXPR bool empty() const {return x1 >= x2 || y1 >= y2;}
left()38     V_CONSTEXPR int left() const {return x1;}
top()39     V_CONSTEXPR int top() const {return y1;}
right()40     V_CONSTEXPR int right() const {return x2;}
bottom()41     V_CONSTEXPR int bottom() const {return y2;}
width()42     V_CONSTEXPR int width() const {return x2-x1;}
height()43     V_CONSTEXPR int height() const {return y2-y1;}
x()44     V_CONSTEXPR int x() const {return x1;}
y()45     V_CONSTEXPR int y() const {return y1;}
size()46     VSize           size() const {return {width(), height()};}
setLeft(int l)47     void            setLeft(int l) { x1 = l; }
setTop(int t)48     void            setTop(int t) { y1 = t; }
setRight(int r)49     void            setRight(int r) { x2 = r; }
setBottom(int b)50     void            setBottom(int b) { y2 = b; }
setWidth(int w)51     void            setWidth(int w) { x2 = x1 + w; }
setHeight(int h)52     void            setHeight(int h) { y2 = y1 + h; }
53     VRect    translated(int dx, int dy) const;
54     void     translate(int dx, int dy);
55     bool     contains(const VRect &r, bool proper = false) const;
56     bool     intersects(const VRect &r);
57     friend V_CONSTEXPR inline bool operator==(const VRect &,
58                                               const VRect &) noexcept;
59     friend V_CONSTEXPR inline bool operator!=(const VRect &,
60                                               const VRect &) noexcept;
61     friend VDebug &                operator<<(VDebug &os, const VRect &o);
62 
63     VRect intersected(const VRect &r) const;
64     VRect operator&(const VRect &r) const;
65 
66 private:
67     int x1{0};
68     int y1{0};
69     int x2{0};
70     int y2{0};
71 };
72 
intersected(const VRect & r)73 inline VRect VRect::intersected(const VRect &r) const
74 {
75     return *this & r;
76 }
77 
intersects(const VRect & r)78 inline bool VRect::intersects(const VRect &r)
79 {
80     return (right() > r.left() && left() < r.right() && bottom() > r.top() &&
81             top() < r.bottom());
82 }
83 
84 inline VDebug &operator<<(VDebug &os, const VRect &o)
85 {
86     os << "{R " << o.x() << "," << o.y() << "," << o.width() << ","
87        << o.height() << "}";
88     return os;
89 }
90 V_CONSTEXPR inline bool operator==(const VRect &r1, const VRect &r2) noexcept
91 {
92     return r1.x1 == r2.x1 && r1.x2 == r2.x2 && r1.y1 == r2.y1 && r1.y2 == r2.y2;
93 }
94 
95 V_CONSTEXPR inline bool operator!=(const VRect &r1, const VRect &r2) noexcept
96 {
97     return r1.x1 != r2.x1 || r1.x2 != r2.x2 || r1.y1 != r2.y1 || r1.y2 != r2.y2;
98 }
99 
translated(int dx,int dy)100 inline VRect VRect::translated(int dx, int dy) const
101 {
102     return {x1 + dx, y1 + dy, x2 - x1, y2 - y1};
103 }
104 
translate(int dx,int dy)105 inline void VRect::translate(int dx, int dy)
106 {
107     x1 += dx;
108     y1 += dy;
109     x2 += dx;
110     y2 += dy;
111 }
112 
contains(const VRect & r,bool proper)113 inline bool VRect::contains(const VRect &r, bool proper) const
114 {
115     return proper ?
116            ((x1 < r.x1) && (x2 > r.x2) && (y1 < r.y1) && (y2 > r.y2)) :
117            ((x1 <= r.x1) && (x2 >= r.x2) && (y1 <= r.y1) && (y2 >= r.y2));
118 }
119 
120 class VRectF {
121 public:
122     VRectF() = default;
123 
VRectF(double x,double y,double w,double h)124     VRectF(double x, double y, double w, double h):
125         x1(float(x)),y1(float(y)),
126         x2(float(x+w)),y2(float(y+h)){}
VRect()127     operator VRect() const {
128         return {int(left()), int(right()), int(width()), int(height())};
129     }
130 
empty()131     V_CONSTEXPR bool  empty() const {return x1 >= x2 || y1 >= y2;}
left()132     V_CONSTEXPR float left() const {return x1;}
top()133     V_CONSTEXPR float top() const {return y1;}
right()134     V_CONSTEXPR float right() const {return x2;}
bottom()135     V_CONSTEXPR float bottom() const {return y2;}
width()136     V_CONSTEXPR float width() const {return x2-x1;}
height()137     V_CONSTEXPR float height() const {return y2-y1;}
x()138     V_CONSTEXPR float x() const {return x1;}
y()139     V_CONSTEXPR float y() const {return y1;}
center()140     V_CONSTEXPR inline VPointF center() const
141     {
142         return {x1 + (x2 - x1) / 2.f, y1 + (y2 - y1) / 2.f};
143     }
setLeft(float l)144     void setLeft(float l) { x1 = l; }
setTop(float t)145     void setTop(float t) { y1 = t; }
setRight(float r)146     void setRight(float r) { x2 = r; }
setBottom(float b)147     void setBottom(float b) { y2 = b; }
setWidth(float w)148     void setWidth(float w) { x2 = x1 + w; }
setHeight(float h)149     void setHeight(float h) { y2 = y1 + h; }
translate(float dx,float dy)150     void translate(float dx, float dy)
151     {
152         x1 += dx;
153         y1 += dy;
154         x2 += dx;
155         y2 += dy;
156     }
157 
158 private:
159     float x1{0};
160     float y1{0};
161     float x2{0};
162     float y2{0};
163 };
164 
VRectF()165 inline VRect::operator VRectF() const
166 {
167        return {double(left()), double(right()), double(width()), double(height())};
168 }
169 
170 V_END_NAMESPACE
171 
172 #endif  // VRECT_H
173