X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fcanvas%2Fimage.cc;h=46cadd0d1cc32008b3c0482725715970c11df2bc;hb=8671e109fcc5089226da1e539bc8b7327b2cb5bf;hp=0c7ce6eb28b190f1e96f7ddb7807d319f706e4f9;hpb=fe344859073b00ff63b0fd0b68c26af6cd96aae3;p=ardour.git diff --git a/libs/canvas/image.cc b/libs/canvas/image.cc index 0c7ce6eb28..46cadd0d1c 100644 --- a/libs/canvas/image.cc +++ b/libs/canvas/image.cc @@ -1,13 +1,39 @@ +/* + Copyright (C) 2013 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + #include "canvas/image.h" #include "gtkmm2ext/gui_thread.h" -#include "pbd/xml++.h" - 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) + , _need_render (false) +{ + DataReady.connect (data_connections, MISSING_INVALIDATOR, boost::bind (&Image::accept_data, this), gui_context()); +} + +Image::Image (Item* parent, Cairo::Format fmt, int width, int height) + : Item (parent) , _format (fmt) , _width (width) , _height (height) @@ -19,19 +45,23 @@ Image::Image (Group* group, Cairo::Format fmt, int width, int height) 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; } + + Rect self = item_to_window (Rect (0, 0, _width, _height)); + boost::optional draw = self.intersection (area); - _current.reset (); - - 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 @@ -42,17 +72,25 @@ Image::compute_bounding_box () const } 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 */ } @@ -61,20 +99,9 @@ void 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 } -XMLNode * -Image::get_state () const -{ - /* XXX */ - return new XMLNode ("Image"); -} - -void -Image::set_state (XMLNode const * /*node*/) -{ - /* XXX */ -}