Mir
rectangle_generic.h
Go to the documentation of this file.
1 /*
2  * Copyright © 2021 Canonical Ltd.
3  *
4  * This program is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License version 2 or 3,
6  * as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Authored by: William Wold <william.wold@canonical.com>
17  */
18 
19 #ifndef MIR_GEOMETRY_RECTANGLE_GENERIC_H_
20 #define MIR_GEOMETRY_RECTANGLE_GENERIC_H_
21 
22 #include "point_generic.h"
23 #include "size_generic.h"
24 #include "displacement_generic.h"
25 
26 #include <ostream>
27 
28 namespace mir
29 {
30 namespace geometry
31 {
32 namespace detail
33 {
34 struct RectangleBase{};
35 }
36 namespace generic
37 {
38 template<typename P, typename S>
40 {
41  constexpr Rectangle() = default;
42 
43  constexpr Rectangle(P const& top_left, S const& size)
45  {
46  }
47 
54  P bottom_right() const
55  {
56  return top_left + as_displacement(size);
57  }
58 
59  P top_right() const
60  {
61  return top_left + as_delta(size.width);
62  }
63 
64  P bottom_left() const
65  {
66  return top_left + as_delta(size.height);
67  }
68 
69  bool contains(P const& p) const
70  {
71  if (size.width == decltype(size.width){} || size.height == decltype(size.height){})
72  return false;
73 
74  auto br = bottom_right();
75  return p.x >= left() && p.x < br.x &&
76  p.y >= top() && p.y < br.y;
77  }
78 
85  bool contains(Rectangle<P, S> const& r) const
86  {
87  return r.left() >= left() &&
88  r.left() + as_delta(r.size.width) <= left() + as_delta(size.width) &&
89  r.top() >= top() &&
90  r.top() + as_delta(r.size.height) <= top() + as_delta(size.height);
91  }
92 
93  bool overlaps(Rectangle<P, S> const& r) const
94  {
95  bool disjoint = r.left() >= right()
96  || r.right() <= left()
97  || r.top() >= bottom()
98  || r.bottom() <= top()
99  || size.width == decltype(size.width){}
100  || size.height == decltype(size.height){}
101  || r.size.width == decltype(r.size.width){}
102  || r.size.height == decltype(r.size.height){};
103  return !disjoint;
104  }
105 
106  Corresponding<P, XTag> left() const { return top_left.x; }
107  Corresponding<P, XTag> right() const { return bottom_right().x; }
108  Corresponding<P, YTag> top() const { return top_left.y; }
110 
112  S size;
113 };
114 
115 template<typename R, typename std::enable_if<std::is_base_of<detail::RectangleBase, R>::value, bool>::type = true>
116 R intersection_of(R const& a, R const& b)
117 {
118  auto const max_left = std::max(a.left(), b.left());
119  auto const min_right = std::min(a.right(), b.right());
120  auto const max_top = std::max(a.top(), b.top());
121  auto const min_bottom = std::min(a.bottom(), b.bottom());
122 
123  if (max_left < min_right && max_top < min_bottom)
124  return {{max_left, max_top},
125  {(min_right - max_left).as_value(),
126  (min_bottom - max_top).as_value()}};
127  else
128  return {};
129 }
130 
131 template<typename P, typename S>
132 inline constexpr bool operator == (Rectangle<P, S> const& lhs, Rectangle<P, S> const& rhs)
133 {
134  return lhs.top_left == rhs.top_left && lhs.size == rhs.size;
135 }
136 
137 template<typename P, typename S>
138 inline constexpr bool operator != (Rectangle<P, S> const& lhs, Rectangle<P, S> const& rhs)
139 {
140  return lhs.top_left != rhs.top_left || lhs.size != rhs.size;
141 }
142 
143 template<typename P, typename S>
144 std::ostream& operator<<(std::ostream& out, Rectangle<P, S> const& value)
145 {
146  out << '(' << value.top_left << ", " << value.size << ')';
147  return out;
148 }
149 }
150 }
151 }
152 
153 #endif // MIR_GEOMETRY_RECTANGLE_GENERIC_H_
std::ostream & operator<<(std::ostream &out, W const &value)
Definition: dimensions_generic.h:144
typename GeometricType::template Corresponding< Tag > Corresponding
Definition: dimensions_generic.h:141
constexpr bool operator!=(D const &lhs, D const &rhs)
Definition: displacement_generic.h:77
R intersection_of(R const &a, R const &b)
Definition: rectangle_generic.h:116
constexpr bool operator==(D const &lhs, D const &rhs)
Definition: displacement_generic.h:71
constexpr S::DisplacementType as_displacement(S const &size)
Definition: displacement_generic.h:162
constexpr T< DeltaXTag > as_delta(T< XTag > const &x)
Definition: dimensions_generic.h:276
Definition: splash_session.h:24
Used for determining if a type is a rectangle.
Definition: rectangle_generic.h:34
Definition: rectangle_generic.h:40
Corresponding< P, XTag > right() const
Definition: rectangle_generic.h:107
P bottom_left() const
Definition: rectangle_generic.h:64
Corresponding< P, YTag > top() const
Definition: rectangle_generic.h:108
P bottom_right() const
The bottom right boundary point of the rectangle.
Definition: rectangle_generic.h:54
constexpr Rectangle(P const &top_left, S const &size)
Definition: rectangle_generic.h:43
P top_left
Definition: rectangle_generic.h:111
bool contains(Rectangle< P, S > const &r) const
Test if the rectangle contains another.
Definition: rectangle_generic.h:85
Corresponding< P, YTag > bottom() const
Definition: rectangle_generic.h:109
Corresponding< P, XTag > left() const
Definition: rectangle_generic.h:106
bool overlaps(Rectangle< P, S > const &r) const
Definition: rectangle_generic.h:93
P top_right() const
Definition: rectangle_generic.h:59
bool contains(P const &p) const
Definition: rectangle_generic.h:69
S size
Definition: rectangle_generic.h:112

Copyright © 2012-2021 Canonical Ltd.
Generated on Wed Jul 28 02:57:36 UTC 2021
This documentation is licensed under the GPL version 2 or 3.