Accessor for ClosedCaptionsDialog.
[dcpomatic.git] / src / lib / rect.h
1 /*
2     Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
6     DCP-o-matic is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     DCP-o-matic is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21 #ifndef DCPOMATIC_RECT_H
22 #define DCPOMATIC_RECT_H
23
24 #include "position.h"
25 #include <boost/optional.hpp>
26 #include <algorithm>
27
28 /* Put this inside a namespace as Apple put a Rect in the global namespace */
29
30 namespace dcpomatic
31 {
32
33 /** @struct Rect
34  *  @brief A rectangle.
35  */
36 template <class T>
37 class Rect
38 {
39 public:
40
41         Rect ()
42                 : x (0)
43                 , y (0)
44                 , width (0)
45                 , height (0)
46         {}
47
48         Rect (Position<T> p, T w_, T h_)
49                 : x (p.x)
50                 , y (p.y)
51                 , width (w_)
52                 , height (h_)
53         {}
54
55         Rect (T x_, T y_, T w_, T h_)
56                 : x (x_)
57                 , y (y_)
58                 , width (w_)
59                 , height (h_)
60         {}
61
62         T x;
63         T y;
64         T width;
65         T height;
66
67         Position<T> position () const
68         {
69                 return Position<T> (x, y);
70         }
71
72         boost::optional<Rect<T> > intersection (Rect<T> const & other) const
73         {
74                 /* This isn't exactly the paragon of mathematical precision */
75
76                 T const tx = std::max (x, other.x);
77                 T const ty = std::max (y, other.y);
78
79                 Rect r (
80                         tx, ty,
81                         std::min (x + width, other.x + other.width) - tx,
82                         std::min (y + height, other.y + other.height) - ty
83                         );
84
85                 if (r.width < 0 || r.height < 0) {
86                         return boost::optional<Rect<T> > ();
87                 }
88
89                 return r;
90         }
91
92         void extend (Rect<T> const & other)
93         {
94                 T old_x = x;
95                 T old_y = y;
96                 x = std::min (x, other.x);
97                 y = std::min (y, other.y);
98                 width = std::max (old_x + width, other.x + other.width) - x;
99                 height = std::max (old_y + height, other.y + other.height) - y;
100         }
101
102         Rect<T> extended (T amount) const {
103                 Rect<T> c = *this;
104                 c.x -= amount;
105                 c.y -= amount;
106                 c.width += amount * 2;
107                 c.height += amount * 2;
108                 return c;
109         }
110
111         bool contains (Position<T> p) const
112         {
113                 return (p.x >= x && p.x <= (x + width) && p.y >= y && p.y <= (y + height));
114         }
115 };
116
117 }
118
119 #endif