clear button states at startup *and* shutdown
[ardour.git] / libs / canvas / image.cc
index 71a5df64dd7ea5bc0aec0967bf5b23c8f62de65f..b42c7053a88267e586c445ca6dbc62ef73a4b2d6 100644 (file)
@@ -22,8 +22,8 @@
 
 using namespace ArdourCanvas;
 
-Image::Image (Group* group, Cairo::Format fmt, int width, int height)
-       : Item (group)
+Image::Image (Canvas* canvas, Cairo::Format fmt, int width, int height)
+       : Item (canvas)
        , _format (fmt)
        , _width (width)
        , _height (height)
@@ -32,11 +32,21 @@ Image::Image (Group* group, Cairo::Format fmt, int width, int height)
        DataReady.connect (data_connections, MISSING_INVALIDATOR, boost::bind (&Image::accept_data, this), gui_context());
 }
 
-void 
+Image::Image (Item* parent, Cairo::Format fmt, int width, int height)
+       : Item (parent)
+       , _format (fmt)
+       , _width (width)
+       , _height (height)
+       , _need_render (false)
+{
+       DataReady.connect (data_connections, MISSING_INVALIDATOR, boost::bind (&Image::accept_data, this), gui_context());
+}
+
+void
 Image::render (Rect const& area, Cairo::RefPtr<Cairo::Context> context) const
 {
        if (_need_render && _pending) {
-               _surface = Cairo::ImageSurface::create (_pending->data.get(),
+               _surface = Cairo::ImageSurface::create (_pending->data,
                                                        _pending->format,
                                                        _pending->width,
                                                        _pending->height,
@@ -44,9 +54,12 @@ Image::render (Rect const& area, Cairo::RefPtr<Cairo::Context> context) const
                _current = _pending;
        }
 
-       if (_surface) {
-               context->set_source (_surface, 0, 0);
-               context->rectangle (area.x0, area.y0, area.width(), area.height());
+       Rect self = item_to_window (Rect (0, 0, _width, _height));
+       boost::optional<Rect> draw = self.intersection (area);
+
+       if (_surface && draw) {
+               context->set_source (_surface, self.x0, self.y0);
+               context->rectangle (draw->x0, draw->y0, draw->width(), draw->height());
                context->fill ();
        }
 }
@@ -59,14 +72,18 @@ Image::compute_bounding_box () const
 }
 
 boost::shared_ptr<Image::Data>
-Image::get_image ()
+Image::get_image (bool allocate_data)
 {
        /* can be called by any thread */
 
        int stride = Cairo::ImageSurface::format_stride_for_width (_format, _width);
-       boost::shared_ptr<Data> d (new Data (boost::shared_array<uint8_t> (new uint8_t[stride*_height]), _width, _height, stride, _format));
-
-       return d;
+       if (allocate_data)  {
+               boost::shared_ptr<Data> d (new Data (new uint8_t[stride*_height], _width, _height, stride, _format));
+               return d;
+       } else {
+               boost::shared_ptr<Data> d (new Data (NULL, _width, _height, stride, _format));
+               return d;
+       }
 }
 
 void
@@ -79,12 +96,12 @@ Image::put_image (boost::shared_ptr<Data> d)
 }
 
 void
-Image::accept_data () 
+Image::accept_data ()
 {
        /* must be executed in gui thread */
 
        begin_change ();
        _need_render = true;
        end_change (); // notify canvas that we need redrawing
-}           
+}