summaryrefslogtreecommitdiff
path: root/libs/canvas/image.cc
blob: a0927451f3cc0a00c650bf43c16d7fec7a40af9e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include "canvas/image.h"

#include "gtkmm2ext/gui_thread.h"

using namespace ArdourCanvas;

Image::Image (Group* group, Cairo::Format fmt, int width, int height)
	: Item (group)
	, _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 (_current) {
		_surface = Cairo::ImageSurface::create (_current->data.get(),
							_current->format,
							_current->width,
							_current->height,
							_current->stride);
	}

	_current.reset ();

	context->set_source (_surface, 0, 0);
	context->rectangle (area.x0, area.y0, area.width(), area.height());
	context->fill ();
}

void
Image::compute_bounding_box () const
{
	_bounding_box = boost::optional<Rect> (Rect (0, 0, _width, _height));
	_bounding_box_dirty = false;
}

boost::shared_ptr<Image::Data>
Image::get_image ()
{
	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;
}

void
Image::put_image (boost::shared_ptr<Data> d)
{
	_pending = d;
	DataReady (); /* EMIT SIGNAL */
}

void
Image::accept_data () 
{
	/* must be executed in gui thread */
	_current = _pending;
	_pending.reset ();
	_need_render = true;
}