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:
parent
a0c5de281a
commit
77f5f4c4bf
|
@ -65,7 +65,10 @@ Arc::render (Rect const & /*area*/, Cairo::RefPtr<Cairo::Context> context) const
|
|||
if (_radius <= 0.0 || _arc_degrees <= 0.0) {
|
||||
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);
|
||||
context->fill_preserve ();
|
||||
setup_outline_context (context);
|
||||
|
|
|
@ -38,7 +38,6 @@ using namespace ArdourCanvas;
|
|||
/** Construct a new Canvas */
|
||||
Canvas::Canvas ()
|
||||
: _root (this)
|
||||
, _log_renders (true)
|
||||
, _scroll_offset_x (0)
|
||||
, _scroll_offset_y (0)
|
||||
{
|
||||
|
@ -68,64 +67,21 @@ Canvas::render (Rect const & area, Cairo::RefPtr<Cairo::Context> const & context
|
|||
}
|
||||
#endif
|
||||
|
||||
// checkpoint ("render", "-> render");
|
||||
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();
|
||||
if (!root_bbox) {
|
||||
/* the root has no bounding box, so there's nothing to render */
|
||||
// checkpoint ("render", "no root bbox");
|
||||
context->restore ();
|
||||
return;
|
||||
}
|
||||
|
||||
boost::optional<Rect> draw = root_bbox.get().intersection (area);
|
||||
boost::optional<Rect> draw = root_bbox->intersection (area);
|
||||
if (draw) {
|
||||
/* there's a common area between the root and the requested
|
||||
area, so render it.
|
||||
*/
|
||||
// checkpoint ("render", "... root");
|
||||
context->stroke ();
|
||||
|
||||
_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&
|
||||
|
@ -502,29 +458,9 @@ GtkCanvas::item_going_away (Item* item, boost::optional<Rect> bounding_box)
|
|||
bool
|
||||
GtkCanvas::on_expose_event (GdkEventExpose* ev)
|
||||
{
|
||||
|
||||
Cairo::RefPtr<Cairo::Context> c = get_window()->create_cairo_context ();
|
||||
|
||||
/* WINDOW CANVAS
|
||||
* 0,0 _scroll_offset_x, _scroll_offset_y
|
||||
*/
|
||||
|
||||
/* render using canvas coordinates */
|
||||
|
||||
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);
|
||||
render (Rect (ev->area.x, ev->area.y, ev->area.x + ev->area.width, ev->area.y + ev->area.height), c);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -79,14 +79,6 @@ public:
|
|||
|
||||
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 window_to_canvas (Rect const&) const;
|
||||
Duple canvas_to_window (Duple const&) const;
|
||||
|
@ -117,9 +109,6 @@ protected:
|
|||
/** our root group */
|
||||
RootGroup _root;
|
||||
|
||||
mutable std::list<Rect> _renders;
|
||||
bool _log_renders;
|
||||
|
||||
Coord _scroll_offset_x;
|
||||
Coord _scroll_offset_y;
|
||||
|
||||
|
|
|
@ -57,7 +57,15 @@ public:
|
|||
virtual ~Item ();
|
||||
|
||||
/** 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;
|
||||
|
||||
|
@ -105,8 +113,13 @@ public:
|
|||
Duple canvas_to_item (Duple const &) const;
|
||||
void item_to_canvas (Coord &, Coord &) 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_window (Duple const&) const;
|
||||
Duple window_to_item (Duple const&) const;
|
||||
Rect item_to_window (Rect const&) const;
|
||||
|
||||
void raise_to_top ();
|
||||
void raise (int);
|
||||
void lower_to_bottom ();
|
||||
|
|
|
@ -78,8 +78,8 @@ Group::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
|
|||
|
||||
#ifdef CANVAS_DEBUG
|
||||
if (DEBUG_ENABLED(PBD::DEBUG::CanvasRender)) {
|
||||
cerr << string_compose ("%1GROUP %2 render %3 items out of %4\n",
|
||||
_canvas->render_indent(), (name.empty() ? string ("[unnamed]") : name), items.size(), _items.size());
|
||||
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(), area);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -105,25 +105,18 @@ Group::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
|
|||
continue;
|
||||
}
|
||||
|
||||
/* convert the render area to our child's coordinates */
|
||||
Rect const item_area = (*i)->parent_to_item (area);
|
||||
|
||||
/* intersect the child's render area with the child's bounding box */
|
||||
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);
|
||||
Rect item = (*i)->item_to_window (item_bbox.get());
|
||||
boost::optional<Rect> draw = item.intersection (area);
|
||||
|
||||
if (draw) {
|
||||
#ifdef CANVAS_DEBUG
|
||||
if (DEBUG_ENABLED(PBD::DEBUG::CanvasRender)) {
|
||||
cerr << string_compose ("%1render %2 %3\n", _canvas->render_indent(), (*i)->whatami(),
|
||||
(*i)->name);
|
||||
}
|
||||
#endif
|
||||
(*i)->render (r.get(), context);
|
||||
(*i)->render (draw.get(), context);
|
||||
++render_count;
|
||||
context->restore ();
|
||||
} else {
|
||||
#ifdef CANVAS_DEBUG
|
||||
if (DEBUG_ENABLED(PBD::DEBUG::CanvasRender)) {
|
||||
|
|
|
@ -43,10 +43,13 @@ Image::render (Rect const& area, Cairo::RefPtr<Cairo::Context> context) const
|
|||
_pending->stride);
|
||||
_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->rectangle (area.x0, area.y0, area.width(), area.height());
|
||||
context->rectangle (draw->x0, draw->y0, draw->width(), draw->height());
|
||||
context->fill ();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,6 +127,20 @@ Item::canvas_to_item (ArdourCanvas::Duple const & d) const
|
|||
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
|
||||
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;
|
||||
}
|
||||
|
||||
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 */
|
||||
void
|
||||
Item::set_position (Duple p)
|
||||
|
|
|
@ -56,8 +56,10 @@ void
|
|||
Line::render (Rect const & /*area*/, Cairo::RefPtr<Cairo::Context> context) const
|
||||
{
|
||||
setup_outline_context (context);
|
||||
context->move_to (_points[0].x, _points[0].y);
|
||||
context->line_to (_points[1].x, _points[1].y);
|
||||
Duple p0 = item_to_window (Duple (_points[0].x, _points[0].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 ();
|
||||
}
|
||||
|
||||
|
|
|
@ -73,8 +73,10 @@ LineSet::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
|
|||
} else if (i->y > area.y0) {
|
||||
set_source_rgba (context, i->color);
|
||||
context->set_line_width (i->width);
|
||||
context->move_to (area.x0, i->y);
|
||||
context->line_to (area.x1, i->y);
|
||||
Duple p0 = item_to_window (Duple (area.x0, 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 ();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,9 +70,11 @@ PolyItem::render_path (Rect const & /*area*/, Cairo::RefPtr<Cairo::Context> cont
|
|||
bool done_first = false;
|
||||
for (Points::const_iterator i = _points.begin(); i != _points.end(); ++i) {
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -95,15 +97,18 @@ PolyItem::render_curve (Rect const & area, Cairo::RefPtr<Cairo::Context> context
|
|||
|
||||
if (done_first) {
|
||||
|
||||
context->curve_to (cp1->x, cp1->y,
|
||||
cp2->x, cp2->y,
|
||||
i->x, i->y);
|
||||
Duple c1 = item_to_window (Duple (cp1->x, cp1->y));
|
||||
Duple c2 = item_to_window (Duple (cp2->x, cp2->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++;
|
||||
cp2++;
|
||||
|
||||
} else {
|
||||
|
||||
Duple c = item_to_window (Duple (i->x, i->y));
|
||||
context->move_to (i->x, i->y);
|
||||
done_first = true;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,9 @@ Polygon::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
|
|||
render_path (area, context);
|
||||
|
||||
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 ();
|
||||
|
|
|
@ -50,7 +50,7 @@ Rectangle::Rectangle (Group* parent, Rect const & rect)
|
|||
}
|
||||
|
||||
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
|
||||
* 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.
|
||||
*/
|
||||
|
||||
Rect plot = _rect;
|
||||
Rect visible = _canvas->visible_area();
|
||||
Duple visible_end = canvas_to_item (Duple (visible.x1, visible.y1));
|
||||
Rect self = item_to_window (_rect);
|
||||
boost::optional<Rect> draw = self.intersection (area);
|
||||
|
||||
plot.x1 = min (plot.x1, visible_end.x);
|
||||
plot.y1 = min (plot.y1, visible_end.y);
|
||||
|
||||
if (_fill) {
|
||||
if (_fill && draw) {
|
||||
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) {
|
||||
context->fill ();
|
||||
|
@ -100,30 +96,30 @@ Rectangle::render (Rect const & /*area*/, Cairo::RefPtr<Cairo::Context> context)
|
|||
*/
|
||||
|
||||
if (!_fill) {
|
||||
context->rectangle (plot.x0, plot.y0, plot.width(), plot.height());
|
||||
context->rectangle (draw->x0, draw->y0, draw->width(), draw->height());
|
||||
context->stroke ();
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (_outline_what & LEFT) {
|
||||
context->move_to (plot.x0, plot.y0);
|
||||
context->line_to (plot.x0, plot.y1);
|
||||
context->move_to (draw->x0, draw->y0);
|
||||
context->line_to (draw->x0, draw->y1);
|
||||
}
|
||||
|
||||
if (_outline_what & BOTTOM) {
|
||||
context->move_to (plot.x0, plot.y1);
|
||||
context->line_to (plot.x1, plot.y1);
|
||||
context->move_to (draw->x0, draw->y1);
|
||||
context->line_to (draw->x1, draw->y1);
|
||||
}
|
||||
|
||||
if (_outline_what & RIGHT) {
|
||||
context->move_to (plot.x1, plot.y0);
|
||||
context->line_to (plot.x1, plot.y1);
|
||||
context->move_to (draw->x1, draw->y0);
|
||||
context->line_to (draw->x1, draw->y1);
|
||||
}
|
||||
|
||||
if (_outline_what & TOP) {
|
||||
context->move_to (plot.x0, plot.y0);
|
||||
context->line_to (plot.x1, plot.y0);
|
||||
context->move_to (draw->x0, draw->y0);
|
||||
context->line_to (draw->x1, draw->y0);
|
||||
}
|
||||
|
||||
context->stroke ();
|
||||
|
|
|
@ -96,6 +96,8 @@ Text::redraw (Cairo::RefPtr<Cairo::Context> context) const
|
|||
* ::render
|
||||
*/
|
||||
|
||||
cerr << "rendered \"" << layout->get_text() << "\" into image\n";
|
||||
|
||||
_need_redraw = false;
|
||||
}
|
||||
|
||||
|
@ -136,7 +138,7 @@ Text::compute_bounding_box () const
|
|||
}
|
||||
|
||||
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()) {
|
||||
return;
|
||||
|
@ -146,8 +148,12 @@ Text::render (Rect const & /*area*/, Cairo::RefPtr<Cairo::Context> context) cons
|
|||
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->rectangle (0, 0, min (_clamped_width, _width), _height);
|
||||
//context->set_source_rgb (0.3, 0.4, 0.02);
|
||||
context->fill ();
|
||||
}
|
||||
|
||||
|
|
|
@ -133,13 +133,13 @@ WaveView::set_samples_per_pixel (double samples_per_pixel)
|
|||
static inline double
|
||||
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
|
||||
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
|
||||
|
@ -151,32 +151,43 @@ WaveView::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
|
|||
return;
|
||||
}
|
||||
|
||||
/* These are all pixel (integer) coordinates from the left hand edge of
|
||||
* the waveview.
|
||||
*/
|
||||
|
||||
double start = area.x0;
|
||||
double const end = area.x1;
|
||||
double const rend = _region->length() / _samples_per_pixel;
|
||||
Rect self = item_to_window (Rect (0.0, 0.0, _region->length() / _samples_per_pixel, _height));
|
||||
boost::optional<Rect> draw = self.intersection (area);
|
||||
|
||||
context->rectangle (self.x0, self.y0, self.width(), self.height());
|
||||
context->set_source_rgb (1.0, 0.0, 0.0);
|
||||
context->stroke ();
|
||||
|
||||
if (!draw) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* pixel coordinates */
|
||||
|
||||
double start = draw->x0;
|
||||
double const end = draw->x1;
|
||||
|
||||
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()) {
|
||||
cerr << "\tsamples " << (*cache)->start() << " .. " << (*cache)->end()
|
||||
<< " pixels "
|
||||
cerr << "\tsample span " << (*cache)->start() << " .. " << (*cache)->end()
|
||||
<< " pixel span "
|
||||
<< to_pixel_offset (_region_start, (*cache)->start(), _samples_per_pixel)
|
||||
<< " .. "
|
||||
<< to_pixel_offset (_region_start, (*cache)->end(), _samples_per_pixel)
|
||||
<< endl;
|
||||
++cache;
|
||||
}
|
||||
|
||||
cache = _cache.begin();
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
/* 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 ()) {
|
||||
|
||||
cerr << "Nothing in cache spans\n";
|
||||
|
||||
/* 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.
|
||||
|
||||
|
@ -209,7 +222,12 @@ WaveView::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
|
|||
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()));
|
||||
|
||||
cerr << "New cache entry for " << start_sample_offset << " .. " << to_src_sample_offset (_region_start, endpoint, _samples_per_pixel)
|
||||
<< endl;
|
||||
|
||||
CacheEntry* c = new CacheEntry (this,
|
||||
start_sample_offset,
|
||||
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.
|
||||
*/
|
||||
|
||||
double end_pixel = min (rend, end);
|
||||
double end_sample_offset = to_src_sample_offset (_region_start, end_pixel, _samples_per_pixel);
|
||||
double end_pixel;
|
||||
double end_sample_offset;
|
||||
int npeaks;
|
||||
|
||||
if (end_sample_offset < (*cache)->start()) {
|
||||
npeaks = end_pixel - start;
|
||||
assert (npeaks > 0);
|
||||
double const rend = _region->length() / _samples_per_pixel;
|
||||
end_sample_offset = to_src_sample_offset (_region_start, end_pixel, _samples_per_pixel);
|
||||
end_pixel = min (rend, end);
|
||||
} else {
|
||||
end_sample_offset = (*cache)->start();
|
||||
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,
|
||||
start_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.
|
||||
*/
|
||||
|
||||
cerr << "found suitable cache entry\n";
|
||||
|
||||
image = *cache;
|
||||
++cache;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
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);
|
||||
#if 0
|
||||
#if 1
|
||||
cerr << "\t\tDraw image between "
|
||||
<< start
|
||||
<< " .. "
|
||||
|
@ -280,8 +306,11 @@ WaveView::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
|
|||
<< endl;
|
||||
#endif
|
||||
|
||||
context->rectangle (start, area.y0, this_end - start, area.height());
|
||||
context->set_source (image->image(), image_origin, 0);
|
||||
cerr << "Fill rect " << draw->x0 << ", " << self.y0 << ' ' << draw->width() << " x " << draw->height() << endl;
|
||||
|
||||
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 ();
|
||||
|
||||
start = this_end;
|
||||
|
|
Loading…
Reference in New Issue
Block a user