basically operational switch to canvas drawing coordinates, although text and waves don't work, and redraw areas are too small

This commit is contained in:
Paul Davis 2013-06-18 08:23:06 -04:00
parent a0c5de281a
commit 77f5f4c4bf
14 changed files with 160 additions and 149 deletions

View file

@ -65,7 +65,10 @@ Arc::render (Rect const & /*area*/, Cairo::RefPtr<Cairo::Context> context) const
if (_radius <= 0.0 || _arc_degrees <= 0.0) { if (_radius <= 0.0 || _arc_degrees <= 0.0) {
return; return;
} }
context->arc (_center.x, _center.y, _radius, _start_degrees * (M_PI/180.0), _arc_degrees * (M_PI/180.0));
Duple c = item_to_window (Duple (_center.x, _center.y));
context->arc (c.x, c.y, _radius, _start_degrees * (M_PI/180.0), _arc_degrees * (M_PI/180.0));
setup_fill_context (context); setup_fill_context (context);
context->fill_preserve (); context->fill_preserve ();
setup_outline_context (context); setup_outline_context (context);

View file

@ -38,7 +38,6 @@ using namespace ArdourCanvas;
/** Construct a new Canvas */ /** Construct a new Canvas */
Canvas::Canvas () Canvas::Canvas ()
: _root (this) : _root (this)
, _log_renders (true)
, _scroll_offset_x (0) , _scroll_offset_x (0)
, _scroll_offset_y (0) , _scroll_offset_y (0)
{ {
@ -68,64 +67,21 @@ Canvas::render (Rect const & area, Cairo::RefPtr<Cairo::Context> const & context
} }
#endif #endif
// checkpoint ("render", "-> render");
render_count = 0; render_count = 0;
context->save ();
#ifdef CANVAS_DEBUG
if (getenv ("ARDOUR_REDRAW_CANVAS")) {
/* light up the canvas to show redraws */
context->set_source_rgba (random()%255 / 255.0,
random()%255 / 255.0,
random()%255 / 255.0,
0.3);
context->rectangle (area.x0, area.y0, area.width(), area.height());
context->fill ();
}
#endif
/* clip to the requested area */
context->rectangle (area.x0, area.y0, area.width(), area.height());
context->clip ();
boost::optional<Rect> root_bbox = _root.bounding_box(); boost::optional<Rect> root_bbox = _root.bounding_box();
if (!root_bbox) { if (!root_bbox) {
/* the root has no bounding box, so there's nothing to render */ /* the root has no bounding box, so there's nothing to render */
// checkpoint ("render", "no root bbox");
context->restore ();
return; return;
} }
boost::optional<Rect> draw = root_bbox.get().intersection (area); boost::optional<Rect> draw = root_bbox->intersection (area);
if (draw) { if (draw) {
/* there's a common area between the root and the requested /* there's a common area between the root and the requested
area, so render it. area, so render it.
*/ */
// checkpoint ("render", "... root");
context->stroke ();
_root.render (*draw, context); _root.render (*draw, context);
} }
if (_log_renders) {
_renders.push_back (area);
}
context->restore ();
#ifdef CANVAS_DEBUG
if (getenv ("ARDOUR_HARLEQUIN_CANVAS")) {
/* light up the canvas to show redraws */
context->set_source_rgba (random()%255 / 255.0,
random()%255 / 255.0,
random()%255 / 255.0,
0.4);
context->rectangle (area.x0, area.y0, area.width(), area.height());
context->fill ();
}
#endif
// checkpoint ("render", "<- render");
} }
ostream& ostream&
@ -502,29 +458,9 @@ GtkCanvas::item_going_away (Item* item, boost::optional<Rect> bounding_box)
bool bool
GtkCanvas::on_expose_event (GdkEventExpose* ev) GtkCanvas::on_expose_event (GdkEventExpose* ev)
{ {
Cairo::RefPtr<Cairo::Context> c = get_window()->create_cairo_context (); Cairo::RefPtr<Cairo::Context> c = get_window()->create_cairo_context ();
/* WINDOW CANVAS
* 0,0 _scroll_offset_x, _scroll_offset_y
*/
/* render using canvas coordinates */ render (Rect (ev->area.x, ev->area.y, ev->area.x + ev->area.width, ev->area.y + ev->area.height), c);
Rect canvas_area (ev->area.x, ev->area.y, ev->area.x + ev->area.width, ev->area.y + ev->area.height);
canvas_area = canvas_area.translate (Duple (_scroll_offset_x, _scroll_offset_y));
/* things are going to render to the cairo surface with canvas
* coordinates:
*
* an item at window/cairo 0,0 will have canvas_coords _scroll_offset_x,_scroll_offset_y
*
* let them render at their natural coordinates by using cairo_translate()
*/
c->translate (-_scroll_offset_x, -_scroll_offset_y);
render (canvas_area, c);
return true; return true;
} }

View file

@ -79,14 +79,6 @@ public:
virtual Cairo::RefPtr<Cairo::Context> context () = 0; virtual Cairo::RefPtr<Cairo::Context> context () = 0;
std::list<Rect> const & renders () const {
return _renders;
}
void set_log_renders (bool log) {
_log_renders = log;
}
Rect canvas_to_window (Rect const&) const; Rect canvas_to_window (Rect const&) const;
Rect window_to_canvas (Rect const&) const; Rect window_to_canvas (Rect const&) const;
Duple canvas_to_window (Duple const&) const; Duple canvas_to_window (Duple const&) const;
@ -117,9 +109,6 @@ protected:
/** our root group */ /** our root group */
RootGroup _root; RootGroup _root;
mutable std::list<Rect> _renders;
bool _log_renders;
Coord _scroll_offset_x; Coord _scroll_offset_x;
Coord _scroll_offset_y; Coord _scroll_offset_y;

View file

@ -57,7 +57,15 @@ public:
virtual ~Item (); virtual ~Item ();
/** Render this item to a Cairo context. /** Render this item to a Cairo context.
* @param area Area to draw in this item's coordinates. * @param area Area to draw, in **window** coordinates
*
* Items must convert their own coordinates into window coordinates
* because Cairo is limited to a fixed point coordinate space that
* does not extend as far as the Ardour timeline. All rendering must
* be done using coordinates that do not exceed the (rough) limits
* of the canvas' window, to avoid odd errors within Cairo as it
* converts doubles into its fixed point format and then tesselates
* the results.
*/ */
virtual void render (Rect const & area, Cairo::RefPtr<Cairo::Context>) const = 0; virtual void render (Rect const & area, Cairo::RefPtr<Cairo::Context>) const = 0;
@ -105,8 +113,13 @@ public:
Duple canvas_to_item (Duple const &) const; Duple canvas_to_item (Duple const &) const;
void item_to_canvas (Coord &, Coord &) const; void item_to_canvas (Coord &, Coord &) const;
Rect item_to_canvas (Rect const &) const; Rect item_to_canvas (Rect const &) const;
Rect canvas_to_item (Rect const &) const;
Duple item_to_canvas (Duple const &) const; Duple item_to_canvas (Duple const &) const;
Duple item_to_window (Duple const&) const;
Duple window_to_item (Duple const&) const;
Rect item_to_window (Rect const&) const;
void raise_to_top (); void raise_to_top ();
void raise (int); void raise (int);
void lower_to_bottom (); void lower_to_bottom ();

View file

@ -78,8 +78,8 @@ Group::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
#ifdef CANVAS_DEBUG #ifdef CANVAS_DEBUG
if (DEBUG_ENABLED(PBD::DEBUG::CanvasRender)) { if (DEBUG_ENABLED(PBD::DEBUG::CanvasRender)) {
cerr << string_compose ("%1GROUP %2 render %3 items out of %4\n", cerr << string_compose ("%1GROUP %2 render %5 %3 items out of %4\n",
_canvas->render_indent(), (name.empty() ? string ("[unnamed]") : name), items.size(), _items.size()); _canvas->render_indent(), (name.empty() ? string ("[unnamed]") : name), items.size(), _items.size(), area);
} }
#endif #endif
@ -105,25 +105,18 @@ Group::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
continue; continue;
} }
/* convert the render area to our child's coordinates */ Rect item = (*i)->item_to_window (item_bbox.get());
Rect const item_area = (*i)->parent_to_item (area); boost::optional<Rect> draw = item.intersection (area);
/* intersect the child's render area with the child's bounding box */ if (draw) {
boost::optional<Rect> r = item_bbox.get().intersection (item_area);
if (r) {
/* render the intersection */
context->save ();
context->translate ((*i)->position().x, (*i)->position().y);
#ifdef CANVAS_DEBUG #ifdef CANVAS_DEBUG
if (DEBUG_ENABLED(PBD::DEBUG::CanvasRender)) { if (DEBUG_ENABLED(PBD::DEBUG::CanvasRender)) {
cerr << string_compose ("%1render %2 %3\n", _canvas->render_indent(), (*i)->whatami(), cerr << string_compose ("%1render %2 %3\n", _canvas->render_indent(), (*i)->whatami(),
(*i)->name); (*i)->name);
} }
#endif #endif
(*i)->render (r.get(), context); (*i)->render (draw.get(), context);
++render_count; ++render_count;
context->restore ();
} else { } else {
#ifdef CANVAS_DEBUG #ifdef CANVAS_DEBUG
if (DEBUG_ENABLED(PBD::DEBUG::CanvasRender)) { if (DEBUG_ENABLED(PBD::DEBUG::CanvasRender)) {

View file

@ -43,10 +43,13 @@ Image::render (Rect const& area, Cairo::RefPtr<Cairo::Context> context) const
_pending->stride); _pending->stride);
_current = _pending; _current = _pending;
} }
Rect self = item_to_window (Rect (0, 0, _width, _height));
boost::optional<Rect> draw = self.intersection (area);
if (_surface) { if (_surface && draw) {
context->set_source (_surface, 0, 0); context->set_source (_surface, 0, 0);
context->rectangle (area.x0, area.y0, area.width(), area.height()); context->rectangle (draw->x0, draw->y0, draw->width(), draw->height());
context->fill (); context->fill ();
} }
} }

View file

@ -127,6 +127,20 @@ Item::canvas_to_item (ArdourCanvas::Duple const & d) const
return d.translate (offset); return d.translate (offset);
} }
ArdourCanvas::Rect
Item::canvas_to_item (ArdourCanvas::Rect const & d) const
{
Item const * i = this;
Duple offset;
while (i) {
offset = offset.translate (-(i->position()));
i = i->parent();
}
return d.translate (offset);
}
void void
Item::item_to_canvas (Coord& x, Coord& y) const Item::item_to_canvas (Coord& x, Coord& y) const
{ {
@ -145,6 +159,24 @@ Item::canvas_to_item (Coord& x, Coord& y) const
y = d.y; y = d.y;
} }
Duple
Item::item_to_window (ArdourCanvas::Duple const & d) const
{
return _canvas->canvas_to_window (item_to_canvas (d));
}
Duple
Item::window_to_item (ArdourCanvas::Duple const & d) const
{
return _canvas->window_to_canvas (canvas_to_item (d));
}
Rect
Item::item_to_window (ArdourCanvas::Rect const & r) const
{
return _canvas->canvas_to_window (item_to_canvas (r));
}
/** Set the position of this item in the parent's coordinates */ /** Set the position of this item in the parent's coordinates */
void void
Item::set_position (Duple p) Item::set_position (Duple p)

View file

@ -56,8 +56,10 @@ void
Line::render (Rect const & /*area*/, Cairo::RefPtr<Cairo::Context> context) const Line::render (Rect const & /*area*/, Cairo::RefPtr<Cairo::Context> context) const
{ {
setup_outline_context (context); setup_outline_context (context);
context->move_to (_points[0].x, _points[0].y); Duple p0 = item_to_window (Duple (_points[0].x, _points[0].y));
context->line_to (_points[1].x, _points[1].y); Duple p1 = item_to_window (Duple (_points[1].x, _points[1].y));
context->move_to (p0.x, p0.y);
context->line_to (p1.x, p1.y);
context->stroke (); context->stroke ();
} }

View file

@ -73,8 +73,10 @@ LineSet::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
} else if (i->y > area.y0) { } else if (i->y > area.y0) {
set_source_rgba (context, i->color); set_source_rgba (context, i->color);
context->set_line_width (i->width); context->set_line_width (i->width);
context->move_to (area.x0, i->y); Duple p0 = item_to_window (Duple (area.x0, i->y));
context->line_to (area.x1, i->y); Duple p1 = item_to_window (Duple (area.x1, i->y));
context->move_to (p0.x, p0.y);
context->line_to (p1.x, p1.y);
context->stroke (); context->stroke ();
} }
} }

View file

@ -70,9 +70,11 @@ PolyItem::render_path (Rect const & /*area*/, Cairo::RefPtr<Cairo::Context> cont
bool done_first = false; bool done_first = false;
for (Points::const_iterator i = _points.begin(); i != _points.end(); ++i) { for (Points::const_iterator i = _points.begin(); i != _points.end(); ++i) {
if (done_first) { if (done_first) {
context->line_to (i->x, i->y); Duple c = item_to_window (Duple (i->x, i->y));
context->line_to (c.x, c.y);
} else { } else {
context->move_to (i->x, i->y); Duple c = item_to_window (Duple (i->x, i->y));
context->move_to (c.x, c.y);
done_first = true; done_first = true;
} }
} }
@ -95,15 +97,18 @@ PolyItem::render_curve (Rect const & area, Cairo::RefPtr<Cairo::Context> context
if (done_first) { if (done_first) {
context->curve_to (cp1->x, cp1->y, Duple c1 = item_to_window (Duple (cp1->x, cp1->y));
cp2->x, cp2->y, Duple c2 = item_to_window (Duple (cp2->x, cp2->y));
i->x, i->y); Duple c3 = item_to_window (Duple (i->x, i->y));
context->curve_to (c1.x, c1.y, c2.x, c2.y, c3.x, c3.y);
cp1++; cp1++;
cp2++; cp2++;
} else { } else {
Duple c = item_to_window (Duple (i->x, i->y));
context->move_to (i->x, i->y); context->move_to (i->x, i->y);
done_first = true; done_first = true;
} }

View file

@ -37,7 +37,9 @@ Polygon::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
render_path (area, context); render_path (area, context);
if (!_points.empty ()) { if (!_points.empty ()) {
context->move_to (_points.front().x, _points.front().y); /* close path */
Duple p = item_to_window (Duple (_points.front().x, _points.front().y));
context->move_to (p.x, p.y);
} }
context->stroke_preserve (); context->stroke_preserve ();

View file

@ -50,7 +50,7 @@ Rectangle::Rectangle (Group* parent, Rect const & rect)
} }
void void
Rectangle::render (Rect const & /*area*/, Cairo::RefPtr<Cairo::Context> context) const Rectangle::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
{ {
/* Cairo goes a little (!) wrong when asked to fill/stroke rectangles that /* Cairo goes a little (!) wrong when asked to fill/stroke rectangles that
* extend way beyond the surface boundaries. To avoid this issue, * extend way beyond the surface boundaries. To avoid this issue,
@ -58,17 +58,13 @@ Rectangle::render (Rect const & /*area*/, Cairo::RefPtr<Cairo::Context> context)
* canvas, converting to item-space coordinates, of course. * canvas, converting to item-space coordinates, of course.
*/ */
Rect plot = _rect; Rect self = item_to_window (_rect);
Rect visible = _canvas->visible_area(); boost::optional<Rect> draw = self.intersection (area);
Duple visible_end = canvas_to_item (Duple (visible.x1, visible.y1));
plot.x1 = min (plot.x1, visible_end.x); if (_fill && draw) {
plot.y1 = min (plot.y1, visible_end.y);
if (_fill) {
setup_fill_context (context); setup_fill_context (context);
cerr << "Fill rect: " << plot << endl;
context->rectangle (plot.x0, plot.y0, plot.width(), plot.height()); context->rectangle (draw->x0, draw->y0, draw->width(), draw->height());
if (!_outline) { if (!_outline) {
context->fill (); context->fill ();
@ -100,30 +96,30 @@ Rectangle::render (Rect const & /*area*/, Cairo::RefPtr<Cairo::Context> context)
*/ */
if (!_fill) { if (!_fill) {
context->rectangle (plot.x0, plot.y0, plot.width(), plot.height()); context->rectangle (draw->x0, draw->y0, draw->width(), draw->height());
context->stroke (); context->stroke ();
} }
} else { } else {
if (_outline_what & LEFT) { if (_outline_what & LEFT) {
context->move_to (plot.x0, plot.y0); context->move_to (draw->x0, draw->y0);
context->line_to (plot.x0, plot.y1); context->line_to (draw->x0, draw->y1);
} }
if (_outline_what & BOTTOM) { if (_outline_what & BOTTOM) {
context->move_to (plot.x0, plot.y1); context->move_to (draw->x0, draw->y1);
context->line_to (plot.x1, plot.y1); context->line_to (draw->x1, draw->y1);
} }
if (_outline_what & RIGHT) { if (_outline_what & RIGHT) {
context->move_to (plot.x1, plot.y0); context->move_to (draw->x1, draw->y0);
context->line_to (plot.x1, plot.y1); context->line_to (draw->x1, draw->y1);
} }
if (_outline_what & TOP) { if (_outline_what & TOP) {
context->move_to (plot.x0, plot.y0); context->move_to (draw->x0, draw->y0);
context->line_to (plot.x1, plot.y0); context->line_to (draw->x1, draw->y0);
} }
context->stroke (); context->stroke ();

View file

@ -96,6 +96,8 @@ Text::redraw (Cairo::RefPtr<Cairo::Context> context) const
* ::render * ::render
*/ */
cerr << "rendered \"" << layout->get_text() << "\" into image\n";
_need_redraw = false; _need_redraw = false;
} }
@ -136,7 +138,7 @@ Text::compute_bounding_box () const
} }
void void
Text::render (Rect const & /*area*/, Cairo::RefPtr<Cairo::Context> context) const Text::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
{ {
if (_text.empty()) { if (_text.empty()) {
return; return;
@ -146,8 +148,12 @@ Text::render (Rect const & /*area*/, Cairo::RefPtr<Cairo::Context> context) cons
redraw (context); redraw (context);
} }
Rect self = item_to_window (Rect (0, 0, min (_clamped_width, _width), _height));
cerr << "Draw \"" << _text << "\" @ " << self.x0 << ", " << self.y0 << ' ' << self.width() << " x " << self.height() << endl;
context->rectangle (self.x0, self.y0, self.width(), self.height());
context->set_source (_image, 0, 0); context->set_source (_image, 0, 0);
context->rectangle (0, 0, min (_clamped_width, _width), _height); //context->set_source_rgb (0.3, 0.4, 0.02);
context->fill (); context->fill ();
} }

View file

@ -133,13 +133,13 @@ WaveView::set_samples_per_pixel (double samples_per_pixel)
static inline double static inline double
to_src_sample_offset (frameoffset_t src_sample_start, double pixel_offset, double spp) to_src_sample_offset (frameoffset_t src_sample_start, double pixel_offset, double spp)
{ {
return src_sample_start + (pixel_offset * spp); return llrintf (src_sample_start + (pixel_offset * spp));
} }
static inline double static inline double
to_pixel_offset (frameoffset_t src_sample_start, double sample_offset, double spp) to_pixel_offset (frameoffset_t src_sample_start, double sample_offset, double spp)
{ {
return (sample_offset - src_sample_start) / spp; return llrintf ((sample_offset - src_sample_start) / spp);
} }
void void
@ -151,32 +151,43 @@ WaveView::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
return; return;
} }
/* These are all pixel (integer) coordinates from the left hand edge of Rect self = item_to_window (Rect (0.0, 0.0, _region->length() / _samples_per_pixel, _height));
* the waveview. boost::optional<Rect> draw = self.intersection (area);
*/
context->rectangle (self.x0, self.y0, self.width(), self.height());
double start = area.x0; context->set_source_rgb (1.0, 0.0, 0.0);
double const end = area.x1; context->stroke ();
double const rend = _region->length() / _samples_per_pixel;
if (!draw) {
return;
}
/* pixel coordinates */
double start = draw->x0;
double const end = draw->x1;
list<CacheEntry*>::iterator cache = _cache.begin (); list<CacheEntry*>::iterator cache = _cache.begin ();
#if 0
cerr << name << " cache contains " << _cache.size() << endl; cerr << name << " draw " << area << "self = " << self << "\n\twill use " << draw.get() << endl;
#if 1
cerr << " Cache contains " << _cache.size() << endl;
while (cache != _cache.end()) { while (cache != _cache.end()) {
cerr << "\tsamples " << (*cache)->start() << " .. " << (*cache)->end() cerr << "\tsample span " << (*cache)->start() << " .. " << (*cache)->end()
<< " pixels " << " pixel span "
<< to_pixel_offset (_region_start, (*cache)->start(), _samples_per_pixel) << to_pixel_offset (_region_start, (*cache)->start(), _samples_per_pixel)
<< " .. " << " .. "
<< to_pixel_offset (_region_start, (*cache)->end(), _samples_per_pixel) << to_pixel_offset (_region_start, (*cache)->end(), _samples_per_pixel)
<< endl; << endl;
++cache; ++cache;
} }
cache = _cache.begin(); cache = _cache.begin();
#endif #endif
while ((end - start) > 1.0) { while ((end - start) > 1.0) {
cerr << "***** RANGE = " << start << " .. " << end << " = " << end - start << endl;
frameoffset_t start_sample_offset = to_src_sample_offset (_region_start, start, _samples_per_pixel); frameoffset_t start_sample_offset = to_src_sample_offset (_region_start, start, _samples_per_pixel);
/* Step through cache entries that end at or before our current position */ /* Step through cache entries that end at or before our current position */
@ -197,6 +208,8 @@ WaveView::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
if (cache == _cache.end ()) { if (cache == _cache.end ()) {
cerr << "Nothing in cache spans\n";
/* Case 1: we have run out of cache entries, so make a new one for /* Case 1: we have run out of cache entries, so make a new one for
the whole required area and put it in the list. the whole required area and put it in the list.
@ -209,7 +222,12 @@ WaveView::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
the region actually is, so clamp with that too. the region actually is, so clamp with that too.
*/ */
double const rend = _region->length() / _samples_per_pixel;
double const endpoint = min (rend, max (end, start + _canvas->visible_area().width())); double const endpoint = min (rend, max (end, start + _canvas->visible_area().width()));
cerr << "New cache entry for " << start_sample_offset << " .. " << to_src_sample_offset (_region_start, endpoint, _samples_per_pixel)
<< endl;
CacheEntry* c = new CacheEntry (this, CacheEntry* c = new CacheEntry (this,
start_sample_offset, start_sample_offset,
to_src_sample_offset (_region_start, endpoint, _samples_per_pixel), to_src_sample_offset (_region_start, endpoint, _samples_per_pixel),
@ -228,20 +246,24 @@ WaveView::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
* or the end of the render area, whichever comes first. * or the end of the render area, whichever comes first.
*/ */
double end_pixel = min (rend, end); double end_pixel;
double end_sample_offset = to_src_sample_offset (_region_start, end_pixel, _samples_per_pixel); double end_sample_offset;
int npeaks; int npeaks;
if (end_sample_offset < (*cache)->start()) { if (end_sample_offset < (*cache)->start()) {
npeaks = end_pixel - start; double const rend = _region->length() / _samples_per_pixel;
assert (npeaks > 0); end_sample_offset = to_src_sample_offset (_region_start, end_pixel, _samples_per_pixel);
end_pixel = min (rend, end);
} else { } else {
end_sample_offset = (*cache)->start(); end_sample_offset = (*cache)->start();
end_pixel = to_pixel_offset (_region_start, end_sample_offset, _samples_per_pixel); end_pixel = to_pixel_offset (_region_start, end_sample_offset, _samples_per_pixel);
npeaks = end_pixel - npeaks;
assert (npeaks > 0);
} }
npeaks = end_pixel - start;
assert (npeaks > 0);
cerr << "New fill-in cache entry for " << start_sample_offset << " .. " << end_sample_offset << endl;
CacheEntry* c = new CacheEntry (this, CacheEntry* c = new CacheEntry (this,
start_sample_offset, start_sample_offset,
end_sample_offset, end_sample_offset,
@ -257,14 +279,18 @@ WaveView::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
we have left, so render it. we have left, so render it.
*/ */
cerr << "found suitable cache entry\n";
image = *cache; image = *cache;
++cache; ++cache;
} }
double this_end = min (end, to_pixel_offset (_region_start, image->end (), _samples_per_pixel)); double this_end = min (end, to_pixel_offset (_region_start, image->end (), _samples_per_pixel));
double const image_origin = to_pixel_offset (_region_start, image->start(), _samples_per_pixel); double const image_origin = to_pixel_offset (_region_start, image->start(), _samples_per_pixel);
#if 0 #if 1
cerr << "\t\tDraw image between " cerr << "\t\tDraw image between "
<< start << start
<< " .. " << " .. "
@ -280,8 +306,11 @@ WaveView::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
<< endl; << endl;
#endif #endif
context->rectangle (start, area.y0, this_end - start, area.height()); cerr << "Fill rect " << draw->x0 << ", " << self.y0 << ' ' << draw->width() << " x " << draw->height() << endl;
context->set_source (image->image(), image_origin, 0);
context->rectangle (start, draw->y0, this_end - start, _height);
// context->set_source (image->image(), image_origin, self.y0 - draw->y0);
context->set_source_rgb (0.0, 0.0, 1.0);
context->fill (); context->fill ();
start = this_end; start = this_end;