Merge branch 'ripple-mode-cc' into cairocanvas
[ardour.git] / libs / canvas / canvas / image.h
1 /*
2     Copyright (C) 2013 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #ifndef __CANVAS_IMAGE__
20 #define __CANVAS_IMAGE__
21
22 #include <stdint.h>
23 #include <boost/shared_ptr.hpp>
24 #include <boost/shared_array.hpp>
25
26 #include "canvas/visibility.h"
27 #include "canvas/item.h"
28
29 typedef void (*ImageReleaseCallback)(uint8_t *d, void *arg);
30
31 namespace ArdourCanvas {
32
33
34 class LIBCANVAS_API Image : public Item
35 {
36 public:
37     Image (Canvas *, Cairo::Format, int width, int height);
38     Image (Item*, Cairo::Format, int width, int height);
39     
40     struct Data {
41         Data (uint8_t *d, int w, int h, int s, Cairo::Format fmt)
42                 : data (d)
43                 , width (w)
44                 , height (h)
45                 , stride (s)
46                 , format (fmt)
47                 , destroy_callback(NULL)
48                 , destroy_arg(NULL)
49         {}
50
51         virtual ~Data () {
52                 if (destroy_callback) {
53                         destroy_callback(data, destroy_arg);
54                 } else {
55                         free(data);
56                 }
57         }
58
59         uint8_t* data;
60         int width;
61         int height;
62         int stride;
63         Cairo::Format format;
64         ImageReleaseCallback  destroy_callback;
65         void* destroy_arg;
66     };
67
68     /** 
69      * Returns a shared_ptr to a Data object that can be used to 
70      * write image data to. The Data object will contain a pointer
71      * to the buffer, along with image properties that may be
72      * useful during the data writing.
73      * 
74      * Can be called from any thread BUT ..
75      *
76      * ... to avoid collisions with Image deletion, some synchronization method
77      * may be required or the use of shared_ptr<Image> or similar.
78      */
79     boost::shared_ptr<Data> get_image (bool allocate_data = true);
80
81
82     /**
83      * Queues a Data object to be used to redraw this Image item
84      * at the earliest possible opportunity.
85      *
86      * May be called from any thread BUT ...
87      *
88      * ... to avoid collisions with Image deletion, some synchronization method
89      * may be required or the use of shared_ptr<Image> or similar.
90      */
91     void put_image (boost::shared_ptr<Data>);
92
93     void render (Rect const &, Cairo::RefPtr<Cairo::Context>) const;
94     void compute_bounding_box () const;
95
96 private:
97     Cairo::Format            _format;
98     int                      _width;
99     int                      _height;
100     int                      _data;
101     mutable boost::shared_ptr<Data>  _current;
102     boost::shared_ptr<Data>  _pending;
103     mutable bool             _need_render;
104     mutable Cairo::RefPtr<Cairo::Surface> _surface;
105
106     void accept_data ();
107     PBD::Signal0<void> DataReady;
108     PBD::ScopedConnectionList data_connections;
109 };
110
111 }
112 #endif