remove debug message
[ardour.git] / libs / canvas / rectangle.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 <iostream>
21 #include <cairomm/context.h>
22 #include "pbd/stacktrace.h"
23 #include "pbd/compose.h"
24
25 #include "canvas/canvas.h"
26 #include "canvas/rectangle.h"
27 #include "canvas/debug.h"
28 #include "canvas/utils.h"
29
30 using namespace std;
31 using namespace ArdourCanvas;
32
33 Rectangle::Rectangle (Group* parent)
34         : Item (parent)
35         , Outline (parent)
36         , Fill (parent)
37         , _outline_what ((What) (LEFT | RIGHT | TOP | BOTTOM))
38 {
39 }
40
41 Rectangle::Rectangle (Group* parent, Rect const & rect)
42         : Item (parent)
43         , Outline (parent)
44         , Fill (parent)
45         , _rect (rect)
46         , _outline_what ((What) (LEFT | RIGHT | TOP | BOTTOM))
47 {
48         
49 }
50
51 void
52 Rectangle::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
53 {
54         Rect self = item_to_window (_rect);
55         boost::optional<Rect> r = self.intersection (area);
56
57         if (!r) {
58                 return;
59         }
60
61         Rect draw = r.get ();
62
63         if (_fill) {
64                 if (_stops.empty()) {
65                         setup_fill_context (context);
66                 } else {
67                         setup_gradient_context (context, self, Duple (draw.x0, draw.y0));
68                 }
69
70                 context->rectangle (draw.x0, draw.y0, draw.width(), draw.height());
71                 context->fill ();
72         } 
73         
74         if (_outline) {
75
76                 setup_outline_context (context);
77                 
78                 /* see the cairo FAQ on single pixel lines to see why we do
79                  * the 0.5 pixel additions.
80                  */
81
82                 if (_outline_what == What (LEFT|RIGHT|BOTTOM|TOP)) {
83                         
84                         context->rectangle (self.x0 + 0.5, self.y0 + 0.5, self.width() - 1.0, self.height() - 1.0);
85
86                 } else {
87
88                         // context->set_line_cap (Cairo::LINE_CAP_SQUARE);
89                         
90                         if (_outline_what & LEFT) {
91                                 /* vertical line: move x-coordinate by 0.5 pixels */
92                                 context->move_to (self.x0 + 0.5, self.y0);
93                                 context->line_to (self.x0 + 0.5, self.y1);
94                         }
95                         
96                         if (_outline_what & BOTTOM) {
97                                 /* horizontal line: move y-coordinate by 0.5 pixels */
98                                 context->move_to (self.x0, self.y1 + 0.5);
99                                 context->line_to (self.x1, self.y1 + 0.5);
100                         }
101                         
102                         if (_outline_what & RIGHT) {
103                                 /* vertical line: move x-coordinate by 0.5 pixels */
104                                 context->move_to (self.x1 + 0.5, self.y0);
105                                 context->line_to (self.x1 + 0.5, self.y1);
106                         }
107                         
108                         if (_outline_what & TOP) {
109                                 /* horizontal line: move y-coordinate by 0.5 pixels */
110                                 context->move_to (self.x0, self.y0 + 0.5);
111                                 context->line_to (self.x1, self.y0 + 0.5);
112                         }
113                 }
114                 
115                 context->stroke ();
116         }
117 }
118
119 void
120 Rectangle::compute_bounding_box () const
121 {
122         if (!_rect.empty()) {
123                 Rect r = _rect.fix ();
124
125                 /* our outlines are always inside our coordinates, but we have
126                  * to ensure that our bounding box fully *contains* the
127                  * rectangle
128                  *
129                  * XXX: or something like that, waffle.
130                  *
131                  */
132                 _bounding_box = _rect.fix ();
133         }
134
135         _bounding_box_dirty = false;
136 }
137
138 void
139 Rectangle::set (Rect const & r)
140 {
141         /* We don't update the bounding box here; it's just
142            as cheap to do it when asked.
143         */
144         
145         begin_change ();
146         
147         _rect = r;
148         
149         _bounding_box_dirty = true;
150         end_change ();
151
152         DEBUG_TRACE (PBD::DEBUG::CanvasItemsDirtied, "canvas item dirty: rectangle change (set)\n");
153 }
154
155 void
156 Rectangle::set_x0 (Coord x0)
157 {
158         begin_change ();
159
160         _rect.x0 = x0;
161
162         _bounding_box_dirty = true;
163         end_change ();
164
165         DEBUG_TRACE (PBD::DEBUG::CanvasItemsDirtied, "canvas item dirty: rectangle change (x0)\n");
166 }
167
168 void
169 Rectangle::set_y0 (Coord y0)
170 {
171         begin_change ();
172         
173         _rect.y0 = y0;
174
175         _bounding_box_dirty = true;
176         end_change();
177
178         DEBUG_TRACE (PBD::DEBUG::CanvasItemsDirtied, "canvas item dirty: rectangle change (y0)\n");
179 }
180
181 void
182 Rectangle::set_x1 (Coord x1)
183 {
184         begin_change ();
185         
186         _rect.x1 = x1;
187
188         _bounding_box_dirty = true;
189         end_change ();
190
191         DEBUG_TRACE (PBD::DEBUG::CanvasItemsDirtied, "canvas item dirty: rectangle change (x1)\n");
192 }
193
194 void
195 Rectangle::set_y1 (Coord y1)
196 {
197         begin_change ();
198
199         _rect.y1 = y1;
200
201         _bounding_box_dirty = true;
202         end_change ();
203
204         DEBUG_TRACE (PBD::DEBUG::CanvasItemsDirtied, "canvas item dirty: rectangle change (y1)\n");
205 }
206
207 void
208 Rectangle::set_outline_what (What what)
209 {
210         begin_change ();
211         
212         _outline_what = what;
213
214         end_change ();
215 }
216
217 void
218 Rectangle::set_outline_what (int what)
219 {
220         set_outline_what ((What) what);
221 }
222