merge with master
[ardour.git] / libs / canvas / types.cc
1 /*
2     Copyright (C) 2011-2013 Paul Davis
3     Author: Carl Hetherington <cth@carlh.net>
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include <algorithm>
21 #include <cfloat>
22 #include <cassert>
23 #include "canvas/types.h"
24
25 using namespace std;
26 using namespace ArdourCanvas;
27
28 Coord const ArdourCanvas::COORD_MAX = 1.7e307;
29
30 static inline Coord
31 safe_add (Coord a, Coord b)
32 {
33         if (((COORD_MAX - a) <= b) || ((COORD_MAX - b) <= a)) {
34                 return COORD_MAX;
35         }
36
37         return a + b;
38 }
39
40 Duple
41 Duple::translate (Duple t) const
42 {
43         Duple d;
44
45         d.x = safe_add (x, t.x);
46         d.y = safe_add (y, t.y);
47         
48         return d;
49 }
50
51 boost::optional<Rect>
52 Rect::intersection (Rect const & o) const
53 {
54         Rect i;
55         
56         i.x0 = max (x0, o.x0);
57         i.y0 = max (y0, o.y0);
58         i.x1 = min (x1, o.x1);
59         i.y1 = min (y1, o.y1);
60
61         if (i.x0 > i.x1 || i.y0 > i.y1) {
62                 return boost::optional<Rect> ();
63         }
64         
65         return boost::optional<Rect> (i);
66 }
67
68 Rect
69 Rect::translate (Duple t) const
70 {
71         Rect r;
72
73         r.x0 = safe_add (x0, t.x);
74         r.y0 = safe_add (y0, t.y);
75         r.x1 = safe_add (x1, t.x);
76         r.y1 = safe_add (y1, t.y);
77         return r;
78 }
79
80 Rect
81 Rect::extend (Rect const & o) const
82 {
83         Rect r;
84         r.x0 = min (x0, o.x0);
85         r.y0 = min (y0, o.y0);
86         r.x1 = max (x1, o.x1);
87         r.y1 = max (y1, o.y1);
88         return r;
89 }
90
91 Rect
92 Rect::expand (Distance amount) const
93 {
94         Rect r;
95         r.x0 = x0 - amount;
96         r.y0 = y0 - amount;
97         r.x1 = safe_add (x1, amount);
98         r.y1 = safe_add (y1, amount);
99         return r;
100 }
101
102 bool
103 Rect::contains (Duple point) const
104 {
105         return point.x >= x0 && point.x <= x1 && point.y >= y0 && point.y <= y1;
106 }
107
108 Rect
109 Rect::fix () const
110 {
111         Rect r;
112         
113         r.x0 = min (x0, x1);
114         r.y0 = min (y0, y1);
115         r.x1 = max (x0, x1);
116         r.y1 = max (y0, y1);
117
118         return r;
119 }
120
121 Duple
122 ArdourCanvas::operator- (Duple const & o)
123 {
124         return Duple (-o.x, -o.y);
125 }
126
127 Duple
128 ArdourCanvas::operator+ (Duple const & a, Duple const & b)
129 {
130         return Duple (safe_add (a.x, b.x), safe_add (a.y, b.y));
131 }
132
133 bool
134 ArdourCanvas::operator== (Duple const & a, Duple const & b)
135 {
136         return a.x == b.x && a.y == b.y;
137 }
138
139 Duple
140 ArdourCanvas::operator- (Duple const & a, Duple const & b)
141 {
142         return Duple (a.x - b.x, a.y - b.y);
143 }
144
145 Duple
146 ArdourCanvas::operator/ (Duple const & a, double b)
147 {
148         return Duple (a.x / b, a.y / b);
149 }
150
151 ostream &
152 ArdourCanvas::operator<< (ostream & s, Duple const & r)
153 {
154         s << "(" << r.x << ", " << r.y << ")";
155         return s;
156 }
157
158 ostream &
159 ArdourCanvas::operator<< (ostream & s, Rect const & r)
160 {
161         s << "[(" << r.x0 << ", " << r.y0 << "), (" << r.x1 << ", " << r.y1 << ") " << r.width() << " x " << r.height() << "]";
162         return s;
163 }
164