ab5056fa3dbd979beff863cedc6dc311938d24d4
[ardour.git] / libs / canvas / fill.cc
1 /*
2  * Copyright (C) 2012 Carl Hetherington <carl@carlh.net>
3  * Copyright (C) 2013-2014 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 #include <cairomm/cairomm.h>
22
23 #include "pbd/compose.h"
24 #include "pbd/convert.h"
25
26 #include "canvas/fill.h"
27 #include "canvas/item.h"
28 #include "canvas/types.h"
29
30 using namespace std;
31 using namespace ArdourCanvas;
32
33 Fill::Fill (Item& self)
34         : _self (self)
35         , _fill_color (0x000000ff)
36         , _fill (true)
37         , _transparent (false)
38 {
39 }
40
41 void
42 Fill::set_fill_color (Gtkmm2ext::Color color)
43 {
44         if (_fill_color != color) {
45                 _self.begin_visual_change ();
46                 _fill_color = color;
47
48                 double r, g, b, a;
49                 Gtkmm2ext::color_to_rgba (color, r, g, b, a);
50                 if (a == 0.0) {
51                         _transparent = true;
52                 } else {
53                         _transparent = false;
54                 }
55
56                 _self.end_visual_change ();
57         }
58 }
59
60 void
61 Fill::set_fill (bool fill)
62 {
63         if (_fill != fill) {
64                 _self.begin_visual_change ();
65                 _fill = fill;
66                 _self.end_visual_change ();
67         }
68 }
69
70 void
71 Fill::setup_fill_context (Cairo::RefPtr<Cairo::Context> context) const
72 {
73         if (_pattern) {
74                 context->set_source (_pattern);
75         } else {
76                                         Gtkmm2ext::set_source_rgba (context, _fill_color);
77         }
78 }
79
80 void
81 Fill::setup_gradient_context (Cairo::RefPtr<Cairo::Context> context, Rect const & self, Duple const & draw_origin) const
82 {
83         Cairo::RefPtr<Cairo::LinearGradient> _gradient;
84
85         if (_vertical_gradient) {
86                 _gradient = Cairo::LinearGradient::create (draw_origin.x, self.y0, draw_origin.x, self.y1);
87         } else {
88                 _gradient = Cairo::LinearGradient::create (self.x0, draw_origin.y, self.x1, draw_origin.y);
89         }
90
91         for (StopList::const_iterator s = _stops.begin(); s != _stops.end(); ++s) {
92                 double r, g, b, a;
93                 Gtkmm2ext::color_to_rgba (s->second, r, g, b, a);
94                 _gradient->add_color_stop_rgba (s->first, r, g, b, a);
95         }
96
97         context->set_source (_gradient);
98 }
99
100 void
101 Fill::set_pattern (Cairo::RefPtr<Cairo::Pattern> p)
102 {
103         _pattern = p;
104 }
105
106 void
107 Fill::set_gradient (StopList const & stops, bool vertical)
108 {
109         _self.begin_visual_change ();
110
111         if (stops.empty()) {
112                 _stops.clear ();
113         } else {
114                 _stops = stops;
115                 _vertical_gradient = vertical;
116         }
117
118         _self.end_visual_change ();
119 }