2 Copyright (C) 2011-2013 Paul Davis
3 Author: Carl Hetherington <cth@carlh.net>
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.
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.
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.
20 #include "canvas/line_set.h"
21 #include "canvas/utils.h"
24 using namespace ArdourCanvas;
28 bool operator() (LineSet::Line const & a, LineSet::Line const & b) {
33 LineSet::LineSet (Canvas* c, Orientation o)
41 LineSet::LineSet (Item* parent, Orientation o)
50 LineSet::compute_bounding_box () const
52 if (_lines.empty ()) {
53 _bounding_box = Rect ();
56 if (_orientation == Horizontal) {
58 _bounding_box = Rect (0, /* x0 */
59 _lines.front().pos - (_lines.front().width/2.0), /* y0 */
61 _lines.back().pos - (_lines.back().width/2.0) /* y1 */
66 _bounding_box = Rect (_lines.front().pos - _lines.front().width/2.0, /* x0 */
68 _lines.back().pos + _lines.back().width/2.0, /* x1 */
74 _bounding_box_dirty = false;
78 LineSet::set_extent (Distance e)
83 _bounding_box_dirty = true;
89 LineSet::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
91 /* area is in window coordinates */
93 for (vector<Line>::const_iterator i = _lines.begin(); i != _lines.end(); ++i) {
97 if (_orientation == Horizontal) {
98 self = item_to_window (Rect (0, i->pos - (i->width/2.0), _extent, i->pos + (i->width/2.0)));
100 self = item_to_window (Rect (i->pos - (i->width/2.0), 0, i->pos + (i->width/2.0), _extent));
103 Rect isect = self.intersection (area);
109 Rect intersection (isect);
111 set_source_rgba (context, i->color);
112 context->set_line_width (i->width);
114 /* Not 100% sure that the computation of the invariant
115 * positions (y and x) below work correctly if the line width
116 * is not 1.0, but visual inspection suggests it is OK.
119 if (_orientation == Horizontal) {
120 double y = self.y0 + ((self.y1 - self.y0)/2.0);
121 context->move_to (intersection.x0, y);
122 context->line_to (intersection.x1, y);
124 double x = self.x0 + ((self.x1 - self.x0)/2.0);
125 context->move_to (x, intersection.y0);
126 context->line_to (x, intersection.y1);
134 LineSet::add (Coord y, Distance width, Color color)
138 _lines.push_back (Line (y, width, color));
139 sort (_lines.begin(), _lines.end(), LineSorter());
141 _bounding_box_dirty = true;
150 _bounding_box_dirty = true;
155 LineSet::covers (Duple const & /*point*/) const
157 /* lines are ordered by position along primary axis, so binary search
158 * to find the place to start looking.