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 
17 #ifndef MIR_GEOMETRY_RECTANGLE_GENERIC_H_
18 #define MIR_GEOMETRY_RECTANGLE_GENERIC_H_
19 
20 #include "point_generic.h"
21 #include "size_generic.h"
22 #include "displacement_generic.h"
23 
24 #include <ostream>
25 
26 namespace mir
27 {
28 namespace geometry
29 {
30 namespace detail
31 {
32 struct RectangleBase{};
33 }
34 namespace generic
35 {
36 template<typename P, typename S>
38 {
39  constexpr Rectangle() = default;
40 
41  constexpr Rectangle(P const& top_left, S const& size)
43  {
44  }
45 
52  P bottom_right() const
53  {
54  return top_left + as_displacement(size);
55  }
56 
57  P top_right() const
58  {
59  return top_left + as_delta(size.width);
60  }
61 
62  P bottom_left() const
63  {
64  return top_left + as_delta(size.height);
65  }
66 
67  bool contains(P const& p) const
68  {
69  if (size.width == decltype(size.width){} || size.height == decltype(size.height){})
70  return false;
71 
72  auto br = bottom_right();
73  return p.x >= left() && p.x < br.x &&
74  p.y >= top() && p.y < br.y;
75  }
76 
83  bool contains(Rectangle<P, S> const& r) const
84  {
85  return r.left() >= left() &&
86  r.left() + as_delta(r.size.width) <= left() + as_delta(size.width) &&
87  r.top() >= top() &&
88  r.top() + as_delta(r.size.height) <= top() + as_delta(size.height);
89  }
90 
91  bool overlaps(Rectangle<P, S> const& r) const
92  {
93  bool disjoint = r.left() >= right()
94  || r.right() <= left()
95  || r.top() >= bottom()
96  || r.bottom() <= top()
97  || size.width == decltype(size.width){}
98  || size.height == decltype(size.height){}
99  || r.size.width == decltype(r.size.width){}
100  || r.size.height == decltype(r.size.height){};
101  return !disjoint;
102  }
103 
104  Corresponding<P, XTag> left() const { return top_left.x; }
105  Corresponding<P, XTag> right() const { return bottom_right().x; }
106  Corresponding<P, YTag> top() const { return top_left.y; }
108 
110  S size;
111 };
112 
113 template<typename R, typename std::enable_if<std::is_base_of<detail::RectangleBase, R>::value, bool>::type = true>
114 R intersection_of(R const& a, R const& b)
115 {
116  auto const max_left = std::max(a.left(), b.left());
117  auto const min_right = std::min(a.right(), b.right());
118  auto const max_top = std::max(a.top(), b.top());
119  auto const min_bottom = std::min(a.bottom(), b.bottom());
120 
121  if (max_left < min_right && max_top < min_bottom)
122  return {{max_left, max_top},
123  {(min_right - max_left).as_value(),
124  (min_bottom - max_top).as_value()}};
125  else
126  return {};
127 }
128 
129 template<typename P, typename S>
130 inline constexpr bool operator == (Rectangle<P, S> const& lhs, Rectangle<P, S> const& rhs)
131 {
132  return lhs.top_left == rhs.top_left && lhs.size == rhs.size;
133 }
134 
135 template<typename P, typename S>
136 inline constexpr bool operator != (Rectangle<P, S> const& lhs, Rectangle<P, S> const& rhs)
137 {
138  return lhs.top_left != rhs.top_left || lhs.size != rhs.size;
139 }
140 
141 template<typename P, typename S>
142 std::ostream& operator<<(std::ostream& out, Rectangle<P, S> const& value)
143 {
144  out << '(' << value.top_left << ", " << value.size << ')';
145  return out;
146 }
147 }
148 }
149 }
150 
151 #endif // MIR_GEOMETRY_RECTANGLE_GENERIC_H_
std::ostream & operator<<(std::ostream &out, W const &value)
Definition: dimensions_generic.h:142
typename GeometricType::template Corresponding< Tag > Corresponding
Definition: dimensions_generic.h:139
constexpr bool operator!=(D const &lhs, D const &rhs)
Definition: displacement_generic.h:75
R intersection_of(R const &a, R const &b)
Definition: rectangle_generic.h:114
constexpr bool operator==(D const &lhs, D const &rhs)
Definition: displacement_generic.h:69
constexpr S::DisplacementType as_displacement(S const &size)
Definition: displacement_generic.h:160
constexpr T< DeltaXTag > as_delta(T< XTag > const &x)
Definition: dimensions_generic.h:274
Definition: splash_session.h:22
Used for determining if a type is a rectangle.
Definition: rectangle_generic.h:32
Definition: rectangle_generic.h:38
Corresponding< P, XTag > right() const
Definition: rectangle_generic.h:105
P bottom_left() const
Definition: rectangle_generic.h:62
Corresponding< P, YTag > top() const
Definition: rectangle_generic.h:106
P bottom_right() const
The bottom right boundary point of the rectangle.
Definition: rectangle_generic.h:52
constexpr Rectangle(P const &top_left, S const &size)
Definition: rectangle_generic.h:41
P top_left
Definition: rectangle_generic.h:109
bool contains(Rectangle< P, S > const &r) const
Test if the rectangle contains another.
Definition: rectangle_generic.h:83
Corresponding< P, YTag > bottom() const
Definition: rectangle_generic.h:107
Corresponding< P, XTag > left() const
Definition: rectangle_generic.h:104
bool overlaps(Rectangle< P, S > const &r) const
Definition: rectangle_generic.h:91
P top_right() const
Definition: rectangle_generic.h:57
bool contains(P const &p) const
Definition: rectangle_generic.h:67
S size
Definition: rectangle_generic.h:110

Copyright © 2012-2022 Canonical Ltd.
Generated on Tue May 24 14:35:34 UTC 2022
This documentation is licensed under the GPL version 2 or 3.