lots of tweaking and adding debug output including operator<</dump(ostream&) methods...
[ardour.git] / libs / canvas / types.cc
1 #include <algorithm>
2 #include <cfloat>
3 #include <cassert>
4 #include "canvas/types.h"
5
6 using namespace std;
7 using namespace ArdourCanvas;
8
9 Coord const ArdourCanvas::COORD_MAX = DBL_MAX;
10 /* XXX: empirically arrived at */
11 Coord const ArdourCanvas::CAIRO_MAX = 65536;
12
13 static inline Coord
14 safe_add (Coord a, Coord b)
15 {
16         if (((COORD_MAX - a) <= b) || ((COORD_MAX - b) <= a)) {
17                 return COORD_MAX;
18         }
19
20         return a + b;
21 }
22
23 Duple
24 Duple::translate (Duple t) const
25 {
26         Duple d;
27
28         d.x = safe_add (x, t.x);
29         d.y = safe_add (y, t.y);
30         
31         return d;
32 }
33
34 boost::optional<Rect>
35 Rect::intersection (Rect const & o) const
36 {
37         Rect i;
38         
39         i.x0 = max (x0, o.x0);
40         i.y0 = max (y0, o.y0);
41         i.x1 = min (x1, o.x1);
42         i.y1 = min (y1, o.y1);
43
44         if (i.x0 > i.x1 || i.y0 > i.y1) {
45                 return boost::optional<Rect> ();
46         }
47         
48         return boost::optional<Rect> (i);
49 }
50
51 Rect
52 Rect::translate (Duple t) const
53 {
54         Rect r;
55         
56         r.x0 = safe_add (x0, t.x);
57         r.y0 = safe_add (y0, t.y);
58         r.x1 = safe_add (x1, t.x);
59         r.y1 = safe_add (y1, t.y);
60         return r;
61 }
62
63 Rect
64 Rect::extend (Rect const & o) const
65 {
66         Rect r;
67         r.x0 = min (x0, o.x0);
68         r.y0 = min (y0, o.y0);
69         r.x1 = max (x1, o.x1);
70         r.y1 = max (y1, o.y1);
71         return r;
72 }
73
74 Rect
75 Rect::expand (Distance amount) const
76 {
77         Rect r;
78         r.x0 = x0 - amount;
79         r.y0 = y0 - amount;
80         r.x1 = safe_add (x1, amount);
81         r.y1 = safe_add (y1, amount);
82         return r;
83 }
84
85 bool
86 Rect::contains (Duple point) const
87 {
88         return point.x >= x0 && point.x <= x1 && point.y >= y0 && point.y <= y1;
89 }
90
91 Rect
92 Rect::fix () const
93 {
94         Rect r;
95         
96         r.x0 = min (x0, x1);
97         r.y0 = min (y0, y1);
98         r.x1 = max (x0, x1);
99         r.y1 = max (y0, y1);
100
101         return r;
102 }
103
104 Duple
105 ArdourCanvas::operator- (Duple const & o)
106 {
107         return Duple (-o.x, -o.y);
108 }
109
110 Duple
111 ArdourCanvas::operator+ (Duple const & a, Duple const & b)
112 {
113         return Duple (safe_add (a.x, b.x), safe_add (a.y, b.y));
114 }
115
116 Duple
117 ArdourCanvas::operator- (Duple const & a, Duple const & b)
118 {
119         return Duple (a.x - b.x, a.y - b.y);
120 }
121
122 Duple
123 ArdourCanvas::operator/ (Duple const & a, double b)
124 {
125         return Duple (a.x / b, a.y / b);
126 }
127
128 ostream &
129 ArdourCanvas::operator<< (ostream & s, Duple const & r)
130 {
131         s << "(" << r.x << ", " << r.y << ")";
132         return s;
133 }
134
135 ostream &
136 ArdourCanvas::operator<< (ostream & s, Rect const & r)
137 {
138         s << "[(" << r.x0 << ", " << r.y0 << "), (" << r.x1 << ", " << r.y1 << ") " << r.width() << " x " << r.height() << "]";
139         return s;
140 }
141