Ardour  9.0-pre0-582-g084a23a80d
canvas/canvas/types.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Carl Hetherington <carl@carlh.net>
3  * Copyright (C) 2013-2017 Paul Davis <paul@linuxaudiosystems.com>
4  * Copyright (C) 2015-2017 Robin Gareus <robin@gareus.org>
5  *
6  * This program 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  * This program 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 along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #ifndef __CANVAS_TYPES_H__
22 #define __CANVAS_TYPES_H__
23 
24 #include <iostream>
25 #include <vector>
26 #include <stdint.h>
27 #include <algorithm>
28 #include <optional>
29 
30 #include <cairomm/refptr.h>
31 
32 #include "gtkmm2ext/colors.h"
33 
34 #include "canvas/visibility.h"
35 
36 namespace Cairo {
37  class Context;
38 }
39 
40 namespace ArdourCanvas
41 {
42 
43 typedef double Coord;
44 typedef double Distance;
45 
46 extern LIBCANVAS_API Coord const COORD_MAX;
47 
49  Horizontal = 0x1,
50  Vertical = 0x2,
51 };
52 
53 inline Coord
55 {
56  if (((COORD_MAX - a) <= b) || ((COORD_MAX - b) <= a)) {
57  return COORD_MAX;
58  }
59 
60  return a + b;
61 }
62 
63 
65 {
66  Duple ()
67  : x (0)
68  , y (0)
69  {}
70 
71  Duple (Coord x_, Coord y_)
72  : x (x_)
73  , y (y_)
74  {}
75 
78 
79  /* alias */
80 
81  Coord width() const { return x; }
82  Coord height() const { return y; }
83 
84  Duple translate (const Duple& t) const throw() {
85  return Duple (canvas_safe_add (x, t.x), canvas_safe_add (y, t.y));
86  }
87 
88  Duple operator- () const throw () {
89  return Duple (-x, -y);
90  }
91  Duple operator+ (Duple const & o) const throw () {
92  return Duple (canvas_safe_add (x, o.x), canvas_safe_add (y, o.y));
93  }
94  bool operator== (Duple const & o) const throw () {
95  return x == o.x && y == o.y;
96  }
97  bool operator!= (Duple const & o) const throw () {
98  return x != o.x || y != o.y;
99  }
100  Duple operator- (Duple const & o) const throw () {
101  return Duple (x - o.x, y - o.y);
102  }
103  Duple operator/ (double b) const throw () {
104  return Duple (x / b, y / b);
105  }
106 };
107 
108 
109 extern LIBCANVAS_API std::ostream & operator<< (std::ostream &, Duple const &);
110 
112 {
113  Rect ()
114  : x0 (0)
115  , y0 (0)
116  , x1 (0)
117  , y1 (0)
118  {}
119 
120  Rect (Coord x0_, Coord y0_, Coord x1_, Coord y1_)
121  : x0 (x0_)
122  , y0 (y0_)
123  , x1 (x1_)
124  , y1 (y1_)
125  {}
126 
131 
132  Rect intersection (Rect const & o) const throw () {
133  Rect i (std::max (x0, o.x0), std::max (y0, o.y0),
134  std::min (x1, o.x1), std::min (y1, o.y1));
135 
136  if (i.x0 > i.x1 || i.y0 > i.y1) {
137  return Rect();
138  }
139 
140  return i;
141  }
142 
143  Rect extend (Rect const & o) const throw () {
144  return Rect (std::min (x0, o.x0), std::min (y0, o.y0),
145  std::max (x1, o.x1), std::max (y1, o.y1));
146  }
147  Rect translate (Duple const& t) const throw () {
148  return Rect (canvas_safe_add (x0, t.x), canvas_safe_add (y0, t.y),
149  canvas_safe_add (x1, t.x),canvas_safe_add (y1, t.y));
150  }
151  Rect expand (Distance amount) const throw () {
152  return Rect (x0 - amount, y0 - amount,
153  canvas_safe_add (x1, amount),
154  canvas_safe_add (y1, amount));
155  }
156  Rect expand (Distance top, Distance right, Distance bottom, Distance left) const throw () {
157  return Rect (x0 - left, y0 - top,
158  canvas_safe_add (x1, right),
159  canvas_safe_add (y1, bottom));
160  }
161 
162  Rect shrink (Distance amount) const throw () {
163  /* This isn't the equivalent of expand (-distance) because
164  of the peculiarities of canvas_safe_add() with negative values.
165  Maybe.
166  */
167  return Rect (canvas_safe_add (x0, amount), canvas_safe_add (y0, amount),
168  x1 - amount, y1 - amount);
169  }
170 
171  Rect shrink (Distance top, Distance right, Distance bottom, Distance left) const throw () {
172  /* This isn't the equivalent of expand (-distance) because
173  of the peculiarities of canvas_safe_add() with negative values.
174  Maybe.
175  */
176  return Rect (canvas_safe_add (x0, left), canvas_safe_add (y0, top),
177  x1 - right, y1 - bottom);
178  }
179 
180  bool contains (Duple const & point) const throw () {
181  return point.x >= x0 && point.x < x1 && point.y >= y0 && point.y < y1;
182  }
183  Rect fix () const throw () {
184  return Rect (std::min (x0, x1), std::min (y0, y1),
185  std::max (x0, x1), std::max (y0, y1));
186  }
187 
188  bool empty() const throw () { return (x0 == x1 && y0 == y1); }
189  operator bool() const throw () { return !empty(); }
190 
191  Distance width () const throw () {
192  return x1 - x0;
193  }
194 
195  Distance height () const throw () {
196  return y1 - y0;
197  }
198  bool operator!= (Rect const & o) const throw () {
199  return x0 != o.x0 ||
200  x1 != o.x1 ||
201  y0 != o.y0 ||
202  y1 != o.y1;
203  }
204 };
205 
207  PackExpand = 0x1, /* use all available space ... */
208  PackFill = 0x2, /* if PackExpand set, this means actually
209  expand size of Item; if PackExpand not
210  set, this does nothing.
211  */
212  PackShrink = 0x4, /* allow Item to be smaller than its natural size */
214  PackFromEnd = 0x10
215 };
216 
222 
223  FourDimensions (Distance u, Distance r = -1., Distance d = -1., Distance l = -1.) {
224 
225  /* CSS style defaults: see https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties
226  */
227 
228  Distance args[4];
229  uint32_t nargs = 1;
230 
231  args[0] = u;
232 
233  if (r >= 0) { args[1] = r; ++nargs; }
234  if (d >= 0) { args[2] = d; ++nargs; }
235  if (l >= 0) { args[3] = l; ++nargs; }
236 
237  switch (nargs) {
238  case 1:
239  up = right = down = left = args[0];
240  break;
241  case 2:
242  up = down = args[0];
243  left = right = args[1];
244  break;
245  case 3:
246  up = args[0];
247  left = right = args[1];
248  down = args[2];
249  break;
250  case 4:
251  up = args[0];
252  right = args[1];
253  down = args[2];
254  left = args[3];
255  break;
256  }
257  }
258 };
259 
260 extern LIBCANVAS_API std::ostream & operator<< (std::ostream &, Rect const &);
261 
262 typedef std::vector<Duple> Points;
263 
264 }
265 
266 #endif
#define LIBCANVAS_API
std::ostream & operator<<(std::ostream &, const ArdourCanvas::Item &)
Coord canvas_safe_add(Coord a, Coord b)
std::vector< Duple > Points
Coord const COORD_MAX
bool operator==(const ProcessorSelection &a, const ProcessorSelection &b)
Duple translate(const Duple &t) const
Duple(Coord x_, Coord y_)
FourDimensions(Distance u, Distance r=-1., Distance d=-1., Distance l=-1.)
Rect intersection(Rect const &o) const
Distance width() const
Rect shrink(Distance amount) const
Rect extend(Rect const &o) const
Rect(Coord x0_, Coord y0_, Coord x1_, Coord y1_)
Rect translate(Duple const &t) const
Rect expand(Distance top, Distance right, Distance bottom, Distance left) const
Distance height() const
Rect expand(Distance amount) const
bool contains(Duple const &point) const
Rect shrink(Distance top, Distance right, Distance bottom, Distance left) const