X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fcanvas%2Fimage.cc;h=fc22af8556f9344a0facfffb855bd125e4477526;hb=e157a84c2b6cb27ef22134c11fde5f277a87e8c7;hp=22ef042cfba542816b73714b04fe35c107fa1663;hpb=37dd7e952bd084cd35a4c4f67949890ee3e7c152;p=ardour.git diff --git a/libs/canvas/image.cc b/libs/canvas/image.cc index 22ef042cfb..fc22af8556 100644 --- a/libs/canvas/image.cc +++ b/libs/canvas/image.cc @@ -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,53 +32,76 @@ 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 context) const { - if (_current) { - _surface = Cairo::ImageSurface::create (_current->data.get(), - _current->format, - _current->width, - _current->height, - _current->stride); + if (_need_render && _pending) { + _surface = Cairo::ImageSurface::create (_pending->data, + _pending->format, + _pending->width, + _pending->height, + _pending->stride); + _current = _pending; } - _current.reset (); + Rect self = item_to_window (Rect (0, 0, _width, _height)); + Rect draw = self.intersection (area); - context->set_source (_surface, 0, 0); - context->rectangle (area.x0, area.y0, area.width(), area.height()); - context->fill (); + if (_surface && draw) { + context->set_source (_surface, self.x0, self.y0); + context->rectangle (draw.x0, draw.y0, draw.width(), draw.height()); + context->fill (); + } } void Image::compute_bounding_box () const { - _bounding_box = boost::optional (Rect (0, 0, _width, _height)); + _bounding_box = Rect (0, 0, _width, _height); _bounding_box_dirty = false; } boost::shared_ptr -Image::get_image () +Image::get_image (bool allocate_data) { - int stride = Cairo::ImageSurface::format_stride_for_width (_format, _width); - boost::shared_ptr d (new Data (boost::shared_array (new uint8_t[stride*_height]), _width, _height, stride, _format)); + /* can be called by any thread */ - return d; + int stride = Cairo::ImageSurface::format_stride_for_width (_format, _width); + if (allocate_data) { + boost::shared_ptr d (new Data (new uint8_t[stride*_height], _width, _height, stride, _format)); + return d; + } else { + boost::shared_ptr d (new Data (NULL, _width, _height, stride, _format)); + return d; + } } void Image::put_image (boost::shared_ptr d) { + /* can be called by any thread */ + _pending = d; DataReady (); /* EMIT SIGNAL */ } void -Image::accept_data () +Image::accept_data () { /* must be executed in gui thread */ - _current = _pending; - _pending.reset (); + + begin_change (); _need_render = true; -} + end_change (); // notify canvas that we need redrawing +}