Merge branch 'master' into cairocanvas
[ardour.git] / libs / canvas / poly_line.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 "canvas/poly_line.h"
21
22 using namespace ArdourCanvas;
23
24 PolyLine::PolyLine (Group* parent)
25         : Item (parent)
26         , PolyItem (parent)
27 {
28
29 }
30
31 void
32 PolyLine::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
33 {
34         if (_outline) {
35                 setup_outline_context (context);
36                 render_path (area, context);
37                 context->stroke ();
38         }
39 }
40
41 bool
42 PolyLine::covers (Duple const & point) const
43 {
44         Duple p = canvas_to_item (point);
45
46         const Points::size_type npoints = _points.size();
47         
48         if (npoints < 2) {
49                 return false;
50         }
51
52         Points::size_type i;
53         Points::size_type j;
54
55         /* repeat for each line segment */
56         
57         for (i = 1, j = 0; i < npoints; ++i, ++j) {
58
59                 /* compute area of triangle computed by the two line points and the one
60                    we are being asked about. If zero (within a given tolerance), the
61                    points are co-linear and the argument is on the line.
62                 */
63
64                 double area = fabs (_points[j].x * (_points[j].y - p.y)) + 
65                                    (_points[i].x * (p.y - _points[j].y)) + 
66                                    (p.x * (_points[j].y - _points[i].y));
67                 if (area < 0.001) {
68                         return true;
69                 }
70         }
71
72         return false;
73 }